我试图用几个参数通过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
。可执行文件的输出提供了以下信息:All parameters after
- 后端are passed to the back end
。
另请注意,有些参数是字符串,有些则不是。
解决方案
现在对我有用:
""" 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))
答案 0 :(得分:24)
在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
)运行脚本,将输出复制并粘贴到另一个命令行,按回车键,看看会发生什么。
c)如果它不起作用,编辑python文件并重复直到它工作。
答案 1 :(得分:0)
首先,你不需要所有这些引用。所以删除它们。当文件名有空格时,你只需要带有文件名的参数的引号(愚蠢的是,Windows经常这样做)。
您的参数只是一个字符串列表,其中一些需要引号。由于Windows对路径分隔符使用非标准\
,因此请为这些名称使用“原始”字符串。
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 )