Pregunta

Traté de llamar a un proceso a través de Python con varios argumentos. Ejecutar el archivo por lotes en sí mismo funciona bien para mí, pero traducirlo a Python me hace gritar. Aquí el contenido del archivo por lotes:

"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 ejecuta el archivo por lotes se denomina cspybat . La salida del ejecutable proporciona la información: Todos los parámetros después de --backend se pasan al back end .

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

Solución

Eso funciona 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))
¿Fue útil?

Solución

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, sino más bien ejecutar el comando en su pregunta directamente desde Python, debe experimentar un poco con el primer argumento para Popen.

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

Entonces, o escribes:

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

Según la documentación:

En Windows: la clase Popen usa CreateProcess () para ejecutar el programa hijo, que opera en cadenas. Si args es una secuencia, se convertirá en una cadena usando el método list2cmdline (). Tenga en cuenta que no todas las aplicaciones de MS Windows interpretan la línea de comandos de la misma manera: list2cmdline () está diseñado para aplicaciones que utilizan las mismas reglas que el tiempo de ejecución de MS C.

Entonces, si usa una secuencia, se convertirá en una cadena. Probablemente intente primero con una secuencia, ya que no tendrá que citar todos los elementos que contienen espacios ( list2cmdline () lo hace por usted).

Para solucionar problemas, le recomiendo que pase su secuencia a subprocess.list2cmdline () y verifique la salida.

Edición :

Esto es lo que haría si fuera usted:

a) Cree un script Python simple ( testparams.py ) como este:

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

b) Ejecute el script desde la línea de comando ( python testparams.py ), copie y pegue el resultado en otra línea de comando, presione Intro y vea qué sucede.

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

Otros consejos

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

Sus parámetros son simplemente una lista de cadenas, algunas de las cuales necesitan comillas. Debido a que Windows usa \ no estándar para un separador de ruta, use " raw " cadenas 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"]

Usa algo como

program = r'"C:\Program Files\Systems\Emb Work 5.4\common\bin\run"'
subprocess.Popen( [program]+params )
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top