2009-11-30 16 views
14

Intenté llamar a un proceso a través de Python con varios argumentos. Ejecutar el archivo por lotes en sí funciona bien para mí, pero traducirlo a Python me hace gritar. Aquí el contenido del archivo por lotes:La ejecución de un subproceso falla

"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" 

el ejecutable que se ejecuta por el archivo por lotes se denomina cspybat. La salida del archivo ejecutable proporciona la información: All parameters after --backend are passed to the back end.

También tenga en cuenta que algunos de los parámetros son cadenas y algunos no.

Solución

que funcione para mí ahora:

""" 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

Se puede publicar algún código real que utilizó? –

+0

vea a continuación ....... – binaryguy

+1

@ wanderameise: No publique información que aclare la pregunta como una "respuesta". NO es una respuesta. Es importante que la información sea parte de la pregunta para que podamos ayudar. Por favor, elimine su falta de respuesta y ACTUALICE su pregunta con la información adicional. –

Respuesta

22

para ejecutar un archivo por lotes en Windows:

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

Si no desea ejecutar el archivo por lotes , pero más bien ejecuta el comando en tu pregunta directamente desde Python, necesitas experimentar un poco con el primer argumento de Popen.

En primer lugar, el primer argumento puede ser una cadena o una secuencia.

Así que o bien escribir:

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"...") 

o

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 

De acuerdo con la documentación:

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.

tanto, si utiliza una secuencia, que se convertirá en una cadena . Probablemente probaré primero con una secuencia, ya que entonces no tendrás que citar todos los elementos que contienen espacios (list2cmdline() lo hace por ti).

Para la solución de problemas, le recomendamos que pase su secuencia a subprocess.list2cmdline() y verifique la salida.

Editar:

Esto es lo que haría si yo fuera usted:

a) Crear un simple script de Python (testparams.py) así:

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

b) Ejecutar la secuencia de comandos desde la línea de comandos (python testparams.py), copie y pegue la salida a otra línea de comando, presione enter y vea qué pasa.

c) Si no funciona, edite el archivo python y repita hasta que funcione.

+0

con respecto a su segunda propuesta: [Error 193]% 1 no es una aplicación Win32 válida – binaryguy

+0

Actualice su pregunta con un fragmento de código que reproduzca el error. – codeape

+0

¡FUNCIONA! ¡¡FANTÁSTICO!! gracias amigo! – binaryguy

0

Primero, usted no necesita todas esas citas. Entonces quítalos. Solo necesita citas sobre los parámetros que tienen un nombre de archivo cuando ese nombre de archivo tiene un espacio (estúpidamente, Windows hace esto a menudo).

Sus parámetros son simplemente una lista de cadenas, algunas de las cuales necesitan comillas. Debido a que Windows usa el \ no estándar para un separador de ruta, use cadenas "en bruto" para estos nombres.

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"] 

usar algo como

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

WindowsError: [Error 3] El sistema no puede encontrar la ruta especificada – binaryguy

+0

¿Cuál? Proporcione detalles actualizando su pregunta. –

+1

@ S.Lott: Creo que no debe citar los parámetros que contienen espacios (en este caso params [0], [1], [2] y [9]. Subprocess.list2cmdline citará parámetros según sea necesario al construir la cadena que se pasa a CreateProcess – codeape

Cuestiones relacionadas