Pergunta

Eu tentei ligar um processo via Python com vários argumentos. Executar o arquivo de lote em si fino trabalha para mim, mas traduzi-la em Python me faz gritar. Aqui o conteúdo do arquivo de lote:

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

O executável que é executado pelo arquivo batch é nomeado cspybat. A saída do executável fornece as informações:. All parameters after - backendare passed to the back end

Observe também que alguns dos parâmetros são strings e alguns não.

Solução

que funciona para mim agora:

    """ 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))
Foi útil?

Solução

Para executar um arquivo de lote do Windows:

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

Se você não quiser executar o arquivo de lote, mas sim executar o comando na sua pergunta diretamente do Python, você precisa experimentar um pouco com o primeiro argumento para Popen.

Em primeiro lugar, o primeiro argumento pode ser uma string ou uma seqüência.

Então você quer escrever:

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

De acordo com a documentação:

No Windows: a classe Popen usa CreateProcess () para executar o programa de criança, que opera em cordas. Se args é uma sequência, que será convertida a uma cadeia utilizando o método list2cmdline (). Por favor, note que nem todas as aplicações MS Windows interpretar a linha de comando da mesma maneira: list2cmdline () é projetado para aplicações que utilizam as mesmas regras que o tempo de execução MS C.

Então, se você usar uma seqüência, ele será convertido para uma string. Eu provavelmente experimentar com uma primeira sequência, desde então você não terá que citar todos os elementos que contêm espaços (list2cmdline() faz isso para você).

Para solucionar o problema, eu recomendo que você passar o seu seqüência para subprocess.list2cmdline() e verifique a saída.

Editar:

Aqui está o que eu faria se eu fosse você:

a) criar um simples script Python (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) Execute o script a partir da linha de comando (python testparams.py), copie e cole a saída para outra linha de comando, pressione enter e ver o que acontece.

c) Se ele não funciona, editar o arquivo de python e repita até que ele funciona.

Outras dicas

Em primeiro lugar, você não necessidade todas aquelas citações. Então, removê-los. Você só precisa de aspas em torno de parâmetros que têm um nome de arquivo quando esse arquivo tem um espaço (estupidamente, o Windows faz isso muitas vezes).

Seus parâmetros são simplesmente uma lista de strings, alguns dos quais necessitam de aspas. Como o Windows usa \ não-padrão para um separador de caminho, use cordas "brutos" para esses nomes.

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

Use algo como

program = r'"C:\Program Files\Systems\Emb Work 5.4\common\bin\run"'
subprocess.Popen( [program]+params )
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top