Question

J'ai essayé d'appeler un processus via Python avec plusieurs arguments. L'exécution du fichier de commandes lui-même me convient, mais sa traduction en Python me fait crier. Voici le contenu du fichier de commandes:

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

L'exécutable exécuté par le fichier de commandes s'appelle cspybat . La sortie de l'exécutable fournit les informations suivantes: Tous les paramètres après - backend sont passés au back-end .

Notez également que certains paramètres sont des chaînes et d'autres pas.

Solution

Cela fonctionne pour moi maintenant:

    """ 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))
Était-ce utile?

La solution

Pour exécuter un fichier de commandes sous Windows:

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

Si vous ne souhaitez pas exécuter le fichier de commandes, mais plutôt exécuter la commande de votre question directement à partir de Python, vous devez expérimenter un peu le premier argument de Popen.

Tout d'abord, le premier argument peut être une chaîne ou une séquence.

Vous écrivez donc soit:

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

ou

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

Selon la documentation:

Sous Windows: la classe Popen utilise CreateProcess () pour exécuter le programme enfant, qui fonctionne sur des chaînes. Si args est une séquence, elle sera convertie en chaîne à l'aide de la méthode list2cmdline (). Veuillez noter que toutes les applications MS Windows n'interprètent pas la ligne de commande de la même manière: list2cmdline () est conçu pour les applications utilisant les mêmes règles que le runtime MS C.

Donc, si vous utilisez une séquence, elle sera convertie en chaîne. J'essaierais probablement d'abord avec une séquence, car vous n'aurez alors pas à citer tous les éléments contenant des espaces ( list2cmdline () le fait pour vous).

Pour résoudre les problèmes, je vous recommande de transmettre votre séquence à subprocess.list2cmdline () et de vérifier le résultat.

Modifier:

Voici ce que je ferais si j'étais vous:

a) Créez un script Python simple ( testparams.py ) comme suit:

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

b) Exécutez le script à partir de la ligne de commande ( python testparams.py ), copiez et collez le résultat dans une autre ligne de commande, appuyez sur Entrée et voyez ce qui se passe.

c) Si cela ne fonctionne pas, éditez le fichier python et répétez l'opération jusqu'à ce que cela fonctionne.

Autres conseils

D'abord, vous n'avez pas besoin de toutes ces citations. Alors enlève-les. Vous n’avez besoin de guillemets autour des paramètres qui ont un nom de fichier quand ce nom de fichier a un espace (bêtement, Windows le fait souvent).

Vos paramètres sont simplement une liste de chaînes, dont certaines ont besoin de guillemets. Etant donné que Windows utilise un \ non standard pour un séparateur de chemin, utilisez " raw " chaînes de caractères pour ces noms.

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

Utilisez quelque chose comme

program = r'"C:\Program Files\Systems\Emb Work 5.4\common\bin\run"'
subprocess.Popen( [program]+params )
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top