执行子进程失败 [英] Executing a subprocess fails

查看:69
本文介绍了执行子进程失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试通过带有多个参数的 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=Cort​​ex-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被传递到后端.

另请注意,有些参数是字符串,有些不是.

解决方案

现在对我有用:

 """单片机刷机功能"""参数 = [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=Cort​​3"、--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"]打印(subprocess.list2cmdline(参数))p = subprocess.Popen(subprocess.list2cmdline(params))

解决方案

在 Windows 中执行批处理文件:

from subprocess import Popenp = Popen("batchfile.bat", cwd=r"c:\directory\包含\batchfile")标准输出,标准错误 = 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"...")# ... 注意你不需要引用包含空格的元素

根据文档:

<块引用>在 Windows 上:Popen 类使用 CreateProcess() 来执行对字符串进行操作的子程序.如果 args 是一个序列,它将使用 list2cmdline() 方法转换为字符串.请注意,并非所有 MS Windows 应用程序都以相同的方式解释命令行:list2cmdline() 是为使用与 MS C 运行时相同规则的应用程序设计的.

所以如果你使用一个序列,它会被转换成一个字符串.我可能会先尝试使用序列,因为这样您就不必引用所有包含空格的元素(list2cmdline() 为您做这件事).

对于故障排除,我建议您将序列传递给 subprocess.list2cmdline() 并检查输出.

如果我是你,我会这样做:

a) 创建一个简单的 Python 脚本 (testparams.py),如下所示:

导入子流程params = [r"C:\Program Files\Systems\Emb Work 5.4\common\bin\run.exe", ...]打印 subprocess.list2cmdline(params)

b) 从命令行 (python testparams.py) 运行脚本,将输出复制并粘贴到另一个命令行,按回车键看看会发生什么.

c) 如果它不起作用,请编辑 python 文件并重复直到它起作用.

I tried to call a process via Python with several arguments. Executing the batch file itself works fine for me but translating it into Python makes me scream. Here the contents of the batch file:

"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" 

The executable that is run by the batch file is named cspybat. The output of the executable provides the information: All parameters after--backendare passed to the back end.

Also note that some of the the parameters are strings and some not.

Solution

That works for me now:

    """ 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))

解决方案

To execute a batch file in Windows:

from subprocess import Popen
p = Popen("batchfile.bat", cwd=r"c:\directory\containing\batchfile")
stdout, stderr = p.communicate()

If you don't want to execute the batch file, but rather execute the command in your question directly from Python, you need to experiment a bit with the first argument to Popen.

First of all, the first argument can either be a string or a sequence.

So you either write:

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"...")

or

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

According to the documentation:

On Windows: the Popen class uses CreateProcess() to execute the child program, which operates on strings. If args is a sequence, it will be converted to a string using the list2cmdline() method. Please note that not all MS Windows applications interpret the command line the same way: list2cmdline() is designed for applications using the same rules as the MS C runtime.

So if you use a sequence, it will be converted to a string. I would probably try with a sequence first, since then you won't have to quote all the elements that contain spaces (list2cmdline() does that for you).

For troubleshooting, I recommend you pass your sequence to subprocess.list2cmdline() and check the output.

Edit:

Here's what I'd do if I were you:

a) Create a simple Python script (testparams.py) like this:

import subprocess
params = [r"C:\Program Files\Systems\Emb Work 5.4\common\bin\run.exe", ...]
print subprocess.list2cmdline(params)

b) Run the script from the command line (python testparams.py), copy and paste the output to another command line, press enter and see what happens.

c) If it does not work, edit the python file and repeat until it works.

这篇关于执行子进程失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆