4

我正在以静默模式运行 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]

执行该命令,但它无法识别该操作并给出有关选择错误选项的错误。我已经交叉验证并发现该命令只能以这种方式工作。

4

4 回答 4

9

问题非常微妙。

您正在直接执行程序。它得到:

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]
    
于 2009-02-09T00:40:21.757 回答
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]
于 2009-02-09T00:35:39.270 回答
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]

我不得不说,那些双引号对我来说看起来不正确。

于 2009-02-09T00:38:00.217 回答
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

)

于 2009-02-09T01:03:07.550 回答