At the end of some processing in Python in Windows I am trying to eject an USB SD card. Researching here it seems there are two ways in which to do it; call a PowerShell program or run PowerShell within Python.
Can anyone offer me any guidance. Please keep it simple; learning Python is my new year project.
So I have written a PowerShell script (ejectusb.ps1) which works perfectly:
$drive = New-Object -ComObject Shell.Application
$drive.Namespace(17).Parsename("J:").InvokeVerb("Eject")
I then call it from Python using subprocess:
subprocess.run(["E:\Data\Computing\Software\MicroSoft\Programming\Powershell\ejectusb.ps1"])
The SD card is not ejected and I get the error messages:
Traceback (most recent call last):
File "E:/Data/Computing/Software/Scripts/SdCardPlayEachVideo06.py", line 91, in <module>
subprocess.run(["E:\Data\Computing\Software\MicroSoft\Programming\Powershell\ejectusb.ps1"])
File "C:\Users\David\AppData\Local\Programs\Python\Python311\Lib\subprocess.py", line 548, in run
with Popen(*popenargs, **kwargs) as process:
File "C:\Users\David\AppData\Local\Programs\Python\Python311\Lib\subprocess.py", line 1024, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "C:\Users\David\AppData\Local\Programs\Python\Python311\Lib\subprocess.py", line 1493, in _execute_child
hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
OSError: [WinError 193] %1 is not a valid Win32 application
I don't understand this error message.
So I tried running PowerShell inside Python using:
os.system('powershell $driveEject = New-Object -comObject Shell.Application;
$driveEject.Namespace(17).ParseName("J:").InvokeVerb("Eject")')
An empty PowerShell screen and also what looks like a Windows command screen briefly flash up, but the SD card is not ejected. No error messages.
Can anyone offer me any guidance. Please keep it simple; learning Python is my new year project.
CodePudding user response:
To run the PowerShell script from Python, you will need to use the subprocess module to call the PowerShell executable and pass the script file as an argument. You can call the script by the following command:
subprocess.run(["powershell", "-File", "E:\Data\Computing\Software\MicroSoft\Programming\Powershell\ejectusb.ps1"])
Alternatively, you could also run the PowerShell commands directly within Python using the subprocess module and the powershell.exe command.
subprocess.run(["powershell", "$drive = New-Object -ComObject Shell.Application; $drive.Namespace(17).Parsename('J:').InvokeVerb('Eject')"])
Make sure the letter of your drive is correct.
CodePudding user response:
Hamed's solution uses the argument 'powershell' to launch PowerShell. i.e
subprocess.run(["powershell", "-File", "E:\Data\Computing\Software\MicroSoft\Programming\Powershell\ejectusb.ps1"])
I have been using the full path to PowerShell as the argument, i.e
subprocess.run(["C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", etc
This path is correct (if I type it into the address bar of Windows File Explorer it launches PowerShell. But is causes a 'file not found' error.
So I dont know what the problem is with the full path but I am grateful for Hamed's workaround.