質問
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"
つまり、2 つの引数ではなく、5 つの引数を受け取る必要があります。
また、 %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]
そうでなければ(私はこの1つは正しいだろうと思います)、これを使用します:
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がエスケープ文字としてバックスラッシュを解釈してすべての問題を回避します。
(例:
>>> s = 'c:\program files\norton antivirus'
>>> print s
c:\program files
orton antivirus
)