子进程.Popen 错误

发布于 2024-07-13 04:47:56 字数 406 浏览 7 评论 0原文

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

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

I am running an msi installer in silent mode and caching logs in the specific file. The following is the command i need to execute.

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

I used:

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

to execute the command however it does not recognise the operation and gives error regarding wrong option selected. I have cross-verified and found that the command only works this way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

っ〆星空下的拥抱 2024-07-20 04:47:56

问题非常微妙。

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

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% 对于程序来说是直接未知的!

有两种方法可以解决此问题:

  1. 调用 shell。

    p = subprocess.Popen('C:\Program Files\ My Installer\Setup.exe /s /v "/qn /lv %TEMP%\log_silent.log"', shell=True) 
      输出 = 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(保险箱[0], 保险箱[1:]) 
      输出 = p.communicate()[0] 
      

The problem is very subtle.

You're executing the program directly. It gets:

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

Whereas it should be:

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

In other words, it should receive 5 arguments, not 2 arguments.

Also, %TEMP% is directly unknown to the program!

There are 2 ways to fix this problem:

  1. Calling the 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. Directly call program (more safer)

    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]
    
别靠近我心 2024-07-20 04:47:56

问题在于,您实际上只向 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]

The problem is that you effectively supply Setup.exe with only one argument. Don't think in terms of the shell, the string you hand over as an argument does not get splitted on spaces anymore, that's your duty!

So, if you are absolutely sure that "/qn /lv %TEMP%\log_silent.log" should be one argument, then use this:

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

Otherwise (I guess this one will be correct), use this:

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s', '/v', '/qn', '/lv', '%TEMP%\log_silent.log'],stdout=subprocess.PIPE).communicate()[0]
浅语花开 2024-07-20 04:47:56

尝试将每个参数放在自己的字符串中(为了可读性而重新格式化):

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

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

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

Try putting each argument in its own string (reformatted for readability):

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

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

I have to say though, those double quotes do not look in the right places to me.

故事和酒 2024-07-20 04:47:56

你说:

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

目录名真的是“My Installer”(有前导空格)吗?

另外,作为一般规则,您应该在路径规范中使用正斜杠。 Python 应该无缝地处理它们(即使在 Windows 上),并且您可以避免 python 将反斜杠解释为转义字符的任何问题。

(例如:

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

You said:

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

Is the directory name really " My Installer" (with a leading space)?

Also, as a general rule, you should use forward slashes in path specifications. Python should handle them seamlessly (even on Windows) and you avoid any problems with python interpreting backslashes as escape characters.

(for example:

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

)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文