erro subprocess.Popen
-
22-08-2019 - |
Pergunta
Estou executando um instalador MSI no modo silencioso e cache de registros no arquivo específico. O seguinte é o comando que eu preciso para executar.
C:\Program Files\ My Installer\Setup.exe /s /v "/qn /lv %TEMP%\log_silent.log"
eu usei:
subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'],stdout=subprocess.PIPE).communicate()[0]
para executar o comando no entanto, não reconhece a operação e dá erro sobre opção errada selecionada. Tenho cross-verificados e descobriu que o comando só funciona desta forma.
Solução
O problema é muito sutil.
Você está executando o programa diretamente. Ele fica:
argv[0] = "C:\Program Files\ My Installer\Setup.exe"
argv[1] = /s /v "/qn /lv %TEMP%\log_silent.log"
Considerando que deve ser:
argv[1] = "/s"
argv[2] = "/v"
argv[3] = "/qn"
argv[4] = "/lv %TEMP%\log_silent.log"
Em outras palavras, ele deve receber 5 argumentos, não 2 argumentos.
Além disso, %TEMP%
é diretamente desconhecido para o programa!
Existem 2 maneiras de corrigir este problema:
-
Chamando o shell.
p = subprocess.Popen('C:\Program Files\ My Installer\Setup.exe /s /v "/qn /lv %TEMP%\log_silent.log"', shell=True) output = p.communicate()[0]
-
programa diretamente chamada (mais seguro)
s = ['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'] safes = [os.path.expandvars(p) for p in argument_string] p = subprocess.Popen(safes[0], safes[1:]) output = p.communicate()[0]
Outras dicas
O problema é que você efetivamente fornecer Setup.exe com apenas um argumento. Não pense em termos de shell, a seqüência de entregar como um argumento não se dividida em espaços mais, que é o seu dever!
Então, se você tem certeza absoluta de que "/ qn / lv% TEMP% \ log_silent.log" deve ser um argumento, em seguida, usar esse:
subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s', '/v', '/qn /lv %TEMP%\log_silent.log'],stdout=subprocess.PIPE).communicate()[0]
Caso contrário (acho que este vai ser correto), use o seguinte:
subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s', '/v', '/qn', '/lv', '%TEMP%\log_silent.log'],stdout=subprocess.PIPE).communicate()[0]
Tente colocar cada argumento em sua própria string (reformatado para facilitar a leitura):
cmd = ['C:\Program Files\ My Installer\Setup.exe',
'/s',
'/v',
'"/qn',
'/lv',
'%TEMP%\log_silent.log"']
subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
Eu tenho que dizer, porém, essas aspas não olhar nos lugares certos para mim.
Você disse:
subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'],stdout=subprocess.PIPE).communicate()[0]
é o nome do diretório realmente "Meu Installer" (com um espaço à esquerda)?
Além disso, como regra geral, você deve usar barras normais em especificações de caminho. Python deve lidar com eles sem problemas (mesmo no Windows) e você evitar quaisquer problemas com python interpretar barras invertidas como caracteres de escape.
(por exemplo:
>>> s = 'c:\program files\norton antivirus'
>>> print s
c:\program files
orton antivirus
)