2009-11-30 11 views
14

Ho provato a chiamare un processo tramite Python con diversi argomenti. L'esecuzione del file batch funziona correttamente, ma la traduzione in Python mi fa urlare. Ecco il contenuto del file batch:L'esecuzione di un sottoprocesso non riesce

"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'eseguibile che viene eseguito dal file batch è denominato cspybat. L'output dell'eseguibile fornisce le informazioni: All parameters after - backend are passed to the back end.

Si noti inoltre che alcuni dei parametri sono stringhe e altri no.

Soluzione

che funziona per me ora:

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

Puoi pubblicare un po 'di codice che è stato utilizzato? –

+0

vedi sotto ....... – binaryguy

+1

@ wanderameise: non pubblicare informazioni che chiariscano la domanda come una "risposta". NON è una risposta. È un'informazione importante che deve far parte della domanda in modo da poter aiutare. CANCELLA la tua mancata risposta e AGGIORNA la tua domanda con le informazioni aggiuntive. –

risposta

22

Per eseguire un file batch in Windows:

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

Se non si desidera eseguire il file batch , ma piuttosto esegui il comando nella tua domanda direttamente da Python, è necessario sperimentare un po 'con il primo argomento su Popen.

Prima di tutto, il primo argomento può essere una stringa o una sequenza.

in modo che sia in scrittura:

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 

Secondo la documentazione:

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.

Quindi, se si utilizza una sequenza, che verrà convertito in una stringa . Probabilmente proverei prima con una sequenza, dato che non dovrai citare tutti gli elementi che contengono spazi (list2cmdline() lo fa per te).

Per la risoluzione dei problemi, si consiglia di passare la sequenza a subprocess.list2cmdline() e controllare l'output.

Edit:

Ecco cosa farei se fossi in te:

a) Creare un semplice script Python (testparams.py) come questo:

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

b) Run lo script dalla riga di comando (python testparams.py), copia e incolla l'output su un'altra riga di comando, premi invio e guarda cosa succede.

c) Se non funziona, modificare il file python e ripetere finché non funziona.

+0

relativo alla seconda proposta: [Errore 193]% 1 non è un'applicazione Win32 valida – binaryguy

+0

Aggiornare la domanda con un frammento di codice che riproduce l'errore. – codeape

+0

FUNZIONA !!! FANTASTICO!! grazie amico! – binaryguy

0

In primo luogo, non è necessario tutte quelle citazioni. Quindi rimuovili. Hai solo bisogno di virgolette intorno ai parametri che hanno un nome di file quando quel nome ha uno spazio (stupidamente, Windows lo fa spesso).

I parametri sono semplicemente un elenco di stringhe, alcune delle quali hanno bisogno di virgolette. Poiché Windows utilizza non standard \ per un separatore di percorso, utilizzare le stringhe "raw" per questi nomi.

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 qualcosa come

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

WindowsError: [Errore 3] Il sistema non riesce a trovare il percorso specificato – binaryguy

+0

Quale? Si prega di fornire dettagli aggiornando la tua domanda. –

+1

@ S.Lott: credo che non dovresti citare i parametri che contengono spazi (in questo caso params [0], [1], [2] e [9]. Subprocess.list2cmdline citerà i parametri necessari quando si costruisce la stringa che viene passato a CreateProcess – codeape