Команда
CMD start
всегда успешно выполняется, если она успешно выполняет данную команду с помощью CreateProcess
или ShellExecuteEx
.Он завершается успешно, даже если ему дано указание /wait
, и в итоге устанавливается %errorlevel%
в ненулевое значение.Вы можете увидеть это, запустив (start /wait exit 1) && echo success
.Оператор &&
выполняет правое выражение только в том случае, если левое выражение выполнено успешно.
Чтобы обойти эту проблему, вы можете вручную выйти из начальной оболочки, используя значение !errorlevel!
, которое устанавливается start
.Например:
command = 'exit 1'
shell_path = os.environ.get('ComSpec', 'cmd.exe')
start_command = 'start "" /wait {}'.format(command)
cmdline = '"{shell}" /v:on /c "({command}) & exit !errorlevel!"'.format(
shell=shell_path, command=start_command)
proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess=PIPE)
Обратите внимание, что в приведенном выше вызове Popen
не используется аргумент shell=True
, поскольку оболочку необходимо запускать вручную с параметром /v:on
.Это дает возможность отложенного расширения переменных окружения, используя "!"вместо "%".
Тем не менее, вам не нужна оболочка для вашей заявленной цели.Просто попросите дочерний процесс создать новую консоль, передав флаг создания CREATE_NEW_CONSOLE
следующим образом:
proc = subprocess.Popen(args, creationflags=subprocess.CREATE_NEW_CONSOLE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)