Redirection with '>' is shell syntax that instructs the shell how to direct the standard output stream of the created process. diskpart doesn't understand it. You can run the command via the shell (whatever COMSPEC
is) with the '/c' option. This should work:
import os
import win32api
shell = os.environ['COMSPEC'] # e.g. cmd.exe
command = r'/c diskpart /s C:\TEMP\mapRHD.dp > C:\TEMP\diskpart.out'
win32api.ShellExecute(0, 'runas', shell, command, '', 1)
Edit:
To get the return code from diskpart, it's simpler to restart your script as an elevated process, as above. The script name is in __file__
, and run sys.executable
. On start, check win32com.shell.shell.IsUserAnAdmin()
for elevated privileges. If the process is elevated, run diskpart with output = subprocess.check_output(r'diskpart /s C:\TEMP\mapRHD.dp')
. You can post-process and log the output as desired.
If the command fails to execute, an OSError
is raised. If diskpart exits with an error, subprocess.CalledProcessError
will be raised, which has the returncode
as an attribute.
A more complicated approach is to use win32com.shell.shell.ShellExecuteEx
, which returns a handle to the new process. By keyword, set fmask = win32com.shell.shellcon.SEE_MASK_NOCLOSEPROCESS
, nShow = win32con.SW_SHOWNORMAL
(or whichever show level you need), lpVerb = 'runas'
, lpFile = os.environ['COMSPEC']
, and lpParameters = command
. You need the value of the hProcess
key (the process handle) from the dict it returns.
Then use win32event.WaitForSingleObject
to wait for the process to close. To wait indefinitely use win32event.INFINITE
. Finally, call win32process.GetExitCodeProcess
to get the exit code. As is, I think running via the shell means this code will either be 0 (success) or 1 (fail), but you could maybe get around that by appending command += " & exit /b %%errorlevel%%"
.