подпроцесс.Всплывающая ошибка
-
22-08-2019 - |
Вопрос
Я запускаю установщик 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 способа устранить эту проблему:
Вызываю оболочку.
p = subprocess.Popen('C:\Program Files\ My Installer\Setup.exe /s /v "/qn /lv %TEMP%\log_silent.log"', shell=True) output = p.communicate()[0]
Прямой вызов программы (более безопасный)
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
)