Вопрос

Я запускаю установщик msi в автоматическом режиме и кэширую журналы в определенном файле.Ниже приведена команда, которую мне нужно выполнить.

C:\Program Files\ My Installer\Setup.exe /s /v "/qn /lv %TEMP%\log_silent.log"

Я использовал:

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'],stdout=subprocess.PIPE).communicate()[0]

чтобы выполнить команду, однако она не распознает операцию и выдает ошибку, связанную с неправильно выбранным параметром.Я провел перекрестную проверку и обнаружил, что команда работает только таким образом.

Это было полезно?

Решение

Проблема очень тонкая.

Вы выполняете программу напрямую.Это становится:

argv[0] = "C:\Program Files\ My Installer\Setup.exe"
argv[1] = /s /v "/qn /lv %TEMP%\log_silent.log"

В то время как это должно быть:

argv[1] = "/s"
argv[2] = "/v"
argv[3] = "/qn"
argv[4] = "/lv %TEMP%\log_silent.log"

Другими словами, он должен получить 5 аргументов, а не 2 аргумента.

Также, %TEMP% непосредственно неизвестен программе!

Есть 2 способа устранить эту проблему:

  1. Вызываю оболочку.

    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. Прямой вызов программы (более безопасный)

    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]
    

Другие советы

Проблема в том, что вы эффективно предоставляете Setup.exe только один аргумент.Не думайте в терминах оболочки, строка, которую вы передаете в качестве аргумента, больше не разбивается на пробелы, это ваша обязанность!

Итак, если вы абсолютно уверены, что "/qn /lv %TEMP%\log_silent.log" должно быть одним аргументом, то используйте это:

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s', '/v', '/qn /lv %TEMP%\log_silent.log'],stdout=subprocess.PIPE).communicate()[0]

В противном случае (я предполагаю, что это будет правильно), используйте это:

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s', '/v', '/qn', '/lv', '%TEMP%\log_silent.log'],stdout=subprocess.PIPE).communicate()[0]

Попробуйте поместить каждый аргумент в отдельную строку (переформатированную для удобства чтения):

cmd = ['C:\Program Files\ My Installer\Setup.exe',
       '/s',
       '/v',
       '"/qn',
       '/lv',
       '%TEMP%\log_silent.log"']

subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]

Однако я должен сказать, что эти двойные кавычки выглядят для меня не в тех местах.

Ты сказал:

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'],stdout=subprocess.PIPE).communicate()[0]

Действительно ли название каталога "Мой установщик" (с начальным пробелом)?

Кроме того, как общее правило, вы должны использовать косые черты в спецификациях пути.Python должен обрабатывать их без проблем (даже в Windows), и вы избежите каких-либо проблем с интерпретацией python обратной косой черты как escape-символов.

(например:

>>> s = 'c:\program files\norton antivirus'
>>> print s
c:\program files
orton antivirus

)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top