2009-11-30 4 views
14

Я попытался вызвать процесс через Python с несколькими аргументами. Выполнение самого командного файла отлично работает для меня, но перевод его на Python заставляет меня кричать. Здесь содержимое пакетного файла:Выполнение сбой подпроцесса

"C:\Program Files\bin\cspybat" "C:\Program Files\bin\armproc.dll" "C:\Program Files\bin\armjlink.dll" "C:\Documents and Settings\USER\Desktop\CAL\testing\Verification\FRT\Code\TC1\Output\Genericb\Debug\Exe\Gen.out" --download_only --backend -B "--endian=little" "--cpu=Cortex-M3" "--fpu=None" "-p" "C:\Program Files\CONFIG\debugger\ST\iostm32f10xxb.ddf" "--drv_verify_download" "--semihosting" "--device=STM32F10xxB" "-d" "jlink" "--drv_communication=USB0" "--jlink_speed=auto" "--jlink_initial_speed=32" "--jlink_reset_strategy=0,0" 

исполняемого файла, который находится в ведении пакетного файла с именем cspybat. Вывод исполняемого файла предоставляет информацию: All parameters after --backend are passed to the back end.

Также обратите внимание, что некоторые из параметров являются строками, а некоторые нет.

Решение

Это работает для меня сейчас:

""" MCU flashing function""" 
params = [r"C:\Program Files\bin\cspy", 
      r"C:\Program Files\bin\arpro.dll", 
      r"C:\Program Files\bin\arjink.dll", 
      r"C:\Documents and Settings\USER\Desktop\Exe\GenerV530b.out", 
      "--download_only", "--backend", "-B", "--endian=little", "--cpu=Cort3", "--fpu=None", "-p", 
      r"C:\Program Files\CONFIG\debugger\ST\iostm32f10xxb.ddf", 
      "--drv_verify_download", "--semihosting", "--device=STM32F10xxB", "-d", "jlink", "--drv_communication=USB0", 
      "--jlink_speed=auto", "--jlink_initial_speed=32", "--jlink_reset_strategy=0,0" ] 
print(subprocess.list2cmdline(params)) 
p = subprocess.Popen(subprocess.list2cmdline(params)) 
+0

Можете ли вы опубликовать некоторые фактические код, который вы использовали? –

+0

см. Ниже ....... – binaryguy

+1

@ wanderameise: Не размещайте информацию, которая разъясняет вопрос как «ответ». Это НЕ ответ. Это важная информация, которая должна быть частью вопроса, чтобы мы могли помочь. УДАЛЯЙТЕ свой ответ без ответа и ОБНОВЛЯЙТЕ свой вопрос с дополнительной информацией. –

ответ

22

Чтобы выполнить пакетный файл в Windows:

from subprocess import Popen 
p = Popen("batchfile.bat", cwd=r"c:\directory\containing\batchfile") 
stdout, stderr = p.communicate() 

Если вы не хотите, чтобы выполнить пакетный файл , а скорее выполните команду в своем вопросе непосредственно с Python, вам нужно немного поэкспериментировать с первым аргументом Popen.

Прежде всего, первый аргумент может быть либо строкой, либо последовательностью.

Так что вы либо записи:

p = Popen(r'"C:\Program Files\Systems\Emb Work 5.4\common\bin\run" "C:\Program Files\Systems\Emb Work 5.4\arm\bin\mpr.dll" ... ...', cwd=r"...") 

или

p = Popen([r"C:\Program Files\Systems\Emb Work 5.4\common\bin\run", r"C:\Program Files\Systems\Emb Work 5.4\arm\bin\mpr.dll", ...], cwd=r"...") 
# ... notice how you don't need to quote the elements containing spaces 

Согласно документации:

On Windows: the Popen class uses CreateProcess() to execute the child program, which operates on strings. If args is a sequence, it will be converted to a string using the list2cmdline() method. Please note that not all MS Windows applications interpret the command line the same way: list2cmdline() is designed for applications using the same rules as the MS C runtime.

Так что, если вы используете последовательность, он будет преобразован в строку , Сначала я бы попытался с первой последовательностью, так как тогда вам не придется указывать все элементы, содержащие пробелы (list2cmdline() делает это для вас).

Для устранения неполадок, я рекомендую вам передать вашу последовательность на subprocess.list2cmdline() и проверить выход.

Edit:

Вот что бы я сделал, если бы я тебя:

а) Создать простой сценарий Python (testparams.py), как это:

import subprocess 
params = [r"C:\Program Files\Systems\Emb Work 5.4\common\bin\run.exe", ...] 
print subprocess.list2cmdline(params) 

б) Выполнить сценарий из командной строки (python testparams.py), скопируйте и вставьте вывод в другую командную строку, нажмите enter и посмотрите, что произойдет.

c) Если это не сработает, отредактируйте файл python и повторите его до тех пор, пока он не будет работать.

+0

относительно вашего второго предложения: [Ошибка 193]% 1 не является допустимым Приложением Win32 – binaryguy

+0

Обновите свой вопрос фрагментом кода, который воспроизводит ошибку. – codeape

+0

ЭТО РАБОТАЕТ !!! ФАНТАСТИКА!! Спасибо приятель! – binaryguy

0

Во-первых, вы не необходимо все эти цитаты. Поэтому удалите их. Вам нужны только котировки вокруг параметров, у которых есть имя файла, когда это имя файла имеет место (глупо, Windows делает это часто).

Ваши параметры - это просто список строк, некоторые из которых нуждаются в кавычках. Поскольку Windows использует нестандартные \ для разделителя путей, используйте «сырые» строки для этих имен.

params = [ 
    r'"C:\Program Files\Systems\Emb Work 5.4\arm\bin\mpr.dll"', 
    r'"C:\Program Files\Systems\Emb Work 5.4\arm\bin\ajl.dll"', 
    r'"C:\Documents and Settings\USER\Desktop\abc.out"', 
    "--backend", 
    "-B", 
    "--endian=little", 
    "--cpu=Cortex", 
    "--fpu=None", 
    "-p", 
    r'"C:\Program Files\unknown\abc.ddf"', 
    "--drv_verify_download", 
    "--semihosting", 
    "--device=STM32F10xxB", 
    "-d", 
    "jjftk", 
    "--drv_communication=USB0", 
    "--speed=auto", 
    "--initial_speed=32", 
    "--reset_strategy=0,0"] 

использовать что-то вроде

program = r'"C:\Program Files\Systems\Emb Work 5.4\common\bin\run"' 
subprocess.Popen([program]+params) 
+0

WindowsError: [Ошибка 3] Система не может найти указанный путь – binaryguy

+0

Какой? Пожалуйста, предоставьте подробную информацию, обновив свой вопрос. –

+1

@ S.Lott: Я верю, что вы не должны указывать параметры, содержащие пробелы (в этом случае params [0], [1], [2] и [9]). Subprocess.list2cmdline будет указывать параметры по мере необходимости при построении строки, которая передается в CreateProcess – codeape

Смежные вопросы