我在静默模式下运行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]
执行命令但是它无法识别操作并且在选择错误选项时出错。我已经交叉验证,发现命令只能这样工作。
答案 0 :(得分:8)
问题非常微妙。
您正在直接执行该程序。得到:
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%
!
有两种方法可以解决此问题:
调用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]
直接致电计划(更安全)
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]
答案 1 :(得分:2)
问题是您只为一个参数提供了Setup.exe。不要以shell的形式来思考,你作为参数交出的字符串不再被分隔在空格上,这是你的职责!
因此,如果您完全确定“/ 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]
答案 2 :(得分: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]
我不得不说,那些双引号并不适合我。
答案 3 :(得分: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将反斜杠解释为转义字符的任何问题。
(例如:
>>> s = 'c:\program files\norton antivirus'
>>> print s
c:\program files
orton antivirus
)