質問
Pythonでいくつかの引数を指定してプロセスを呼び出そうとしました。バッチファイル自体の実行はうまくいきますが、Pythonに変換すると悲鳴が上がります。バッチファイルの内容は次のとおりです。
"C:\Program Files\bin\cspybat" "C:\Program Files\bin\armproc.dll" "C:\Program Files\bin\armjlink.dll" "C:\Documents and Settings\USER\Desktop\CAL\testing\Verification\FRT\Code\TC1\Output\Genericb\Debug\Exe\Gen.out" --download_only --backend -B "--endian=little" "--cpu=Cortex-M3" "--fpu=None" "-p" "C:\Program Files\CONFIG\debugger\ST\iostm32f10xxb.ddf" "--drv_verify_download" "--semihosting" "--device=STM32F10xxB" "-d" "jlink" "--drv_communication=USB0" "--jlink_speed=auto" "--jlink_initial_speed=32" "--jlink_reset_strategy=0,0"
バッチファイルによって実行される実行可能ファイルの名前は cspybat
です。実行可能ファイルの出力は次の情報を提供します。すべてのパラメーター
-backend バックエンドに渡されます
。
また、パラメータの一部は文字列であり、一部は文字列ではないことに注意してください。
解決策
それは今私のために働く:
""" MCU flashing function"""
params = [r"C:\Program Files\bin\cspy",
r"C:\Program Files\bin\arpro.dll",
r"C:\Program Files\bin\arjink.dll",
r"C:\Documents and Settings\USER\Desktop\Exe\GenerV530b.out",
"--download_only", "--backend", "-B", "--endian=little", "--cpu=Cort3", "--fpu=None", "-p",
r"C:\Program Files\CONFIG\debugger\ST\iostm32f10xxb.ddf",
"--drv_verify_download", "--semihosting", "--device=STM32F10xxB", "-d", "jlink", "--drv_communication=USB0",
"--jlink_speed=auto", "--jlink_initial_speed=32", "--jlink_reset_strategy=0,0" ]
print(subprocess.list2cmdline(params))
p = subprocess.Popen(subprocess.list2cmdline(params))
解決
Windowsでバッチファイルを実行するには:
from subprocess import Popen
p = Popen("batchfile.bat", cwd=r"c:\directory\containing\batchfile")
stdout, stderr = p.communicate()
バッチファイルを実行したくないが、Pythonから直接質問のコマンドを実行する場合は、Popenの最初の引数を少し試す必要があります。
まず、最初の引数は文字列またはシーケンスのいずれかです。
したがって、次のいずれかを記述します。
p = Popen(r'"C:\Program Files\Systems\Emb Work 5.4\common\bin\run" "C:\Program Files\Systems\Emb Work 5.4\arm\bin\mpr.dll" ... ...', cwd=r"...")
または
p = Popen([r"C:\Program Files\Systems\Emb Work 5.4\common\bin\run", r"C:\Program Files\Systems\Emb Work 5.4\arm\bin\mpr.dll", ...], cwd=r"...")
# ... notice how you don't need to quote the elements containing spaces
ドキュメントによると:
Windowsの場合:Popenクラスは、CreateProcess()を使用して、文字列を操作する子プログラムを実行します。 argsがシーケンスの場合、list2cmdline()メソッドを使用して文字列に変換されます。すべてのMS Windowsアプリケーションが同じようにコマンドラインを解釈するわけではないことに注意してください。list2cmdline()は、MS Cランタイムと同じルールを使用するアプリケーション用に設計されています。
したがって、シーケンスを使用する場合、文字列に変換されます。スペースを含むすべての要素を引用符で囲む必要はありません( list2cmdline()
が自動的に行います)。
トラブルシューティングのために、シーケンスを subprocess.list2cmdline()
に渡し、出力を確認することをお勧めします。
編集:
ここに私があなただったらどうする?
a)次のような単純なPythonスクリプト( testparams.py
)を作成します:
import subprocess
params = [r"C:\Program Files\Systems\Emb Work 5.4\common\bin\run.exe", ...]
print subprocess.list2cmdline(params)
b)コマンドライン( python testparams.py
)からスクリプトを実行し、出力をコピーして別のコマンドラインに貼り付け、Enterキーを押して何が起こるかを確認します。
c)機能しない場合は、pythonファイルを編集し、機能するまで繰り返します。
他のヒント
最初に、これらすべての引用符を必要としない。それらを削除します。ファイル名にスペースがある場合にのみ、ファイル名を持つパラメーターを引用符で囲む必要があります(愚かなことに、Windowsはこれを頻繁に行います)。
パラメータは単なる文字列のリストであり、一部には引用符が必要です。 Windowsはパス区切り文字に非標準の \
を使用しているため、" raw"を使用してください。これらの名前の文字列。
params = [
r'"C:\Program Files\Systems\Emb Work 5.4\arm\bin\mpr.dll"',
r'"C:\Program Files\Systems\Emb Work 5.4\arm\bin\ajl.dll"',
r'"C:\Documents and Settings\USER\Desktop\abc.out"',
"--backend",
"-B",
"--endian=little",
"--cpu=Cortex",
"--fpu=None",
"-p",
r'"C:\Program Files\unknown\abc.ddf"',
"--drv_verify_download",
"--semihosting",
"--device=STM32F10xxB",
"-d",
"jjftk",
"--drv_communication=USB0",
"--speed=auto",
"--initial_speed=32",
"--reset_strategy=0,0"]
次のようなものを使用します
program = r'"C:\Program Files\Systems\Emb Work 5.4\common\bin\run"'
subprocess.Popen( [program]+params )