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"

つまり、2 つの引数ではなく、5 つの引数を受け取る必要があります。

また、%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 に実質的に引数を 1 つしか指定しないことです。シェルの観点から考えないでください。引数として渡す文字列は、スペースで分割されなくなります。それがあなたの義務です!

したがって、"/qn /lv %TEMP%\log_silent.log" が 1 つの引数であることが絶対に確実な場合は、次のように使用します。

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

あなたが言った:

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 に答える
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 に答える