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.

Foi útil?

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:

  1. 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]
    
  2. 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

)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top