Executing a subprocess fails

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 Filesbincspybat" "C:Program Filesbinarmproc.dll" "C:Program Filesbinarmjlink.dll" "C:Documents and SettingsUSERDesktopCALtestingVerificationFRTCodeTC1OutputGenericbDebugExeGen.out" --download_only --backend -B "--endian=little" "--cpu=Cortex-M3" "--fpu=None" "-p" "C:Program FilesCONFIGdebuggerSTiostm32f10xxb.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 Filesbincspy",
          r"C:Program Filesbinarpro.dll",
          r"C:Program Filesbinarjink.dll",
          r"C:Documents and SettingsUSERDesktopExeGenerV530b.out",
          "--download_only", "--backend", "-B", "--endian=little", "--cpu=Cort3", "--fpu=None", "-p", 
          r"C:Program FilesCONFIGdebuggerSTiostm32f10xxb.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))

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

To execute a batch file in Windows:

from subprocess import Popen
p = Popen("batchfile.bat", cwd=r"c:directorycontainingbatchfile")
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 FilesSystemsEmb Work 5.4commonbinrun" "C:Program FilesSystemsEmb Work 5.4armbinmpr.dll" ... ...', cwd=r"...")

or

p = Popen([r"C:Program FilesSystemsEmb Work 5.4commonbinrun", r"C:Program FilesSystemsEmb Work 5.4armbinmpr.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 FilesSystemsEmb Work 5.4commonbinrun.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.

Method 2

First, you don’t need all those quotes. So remove them. You only need quotes around parameters that have a filename when that filename has a space (stupidly, Windows does this often).

Your parameters are simply a list of strings, some of which need quotes. Because Windows uses non-standard for a path separator, use “raw” strings for these names.

params = [
    r'"C:Program FilesSystemsEmb Work 5.4armbinmpr.dll"',
    r'"C:Program FilesSystemsEmb Work 5.4armbinajl.dll"',
    r'"C:Documents and SettingsUSERDesktopabc.out"',
    "--backend",
    "-B", 
    "--endian=little",
    "--cpu=Cortex",
    "--fpu=None",
    "-p",
    r'"C:Program Filesunknownabc.ddf"',
    "--drv_verify_download",
    "--semihosting",
    "--device=STM32F10xxB",
    "-d",
    "jjftk",
    "--drv_communication=USB0",
    "--speed=auto",
    "--initial_speed=32",
    "--reset_strategy=0,0"]

Use something like

program = r'"C:Program FilesSystemsEmb Work 5.4commonbinrun"'
subprocess.Popen( [program]+params )


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x