Command prompt not shown when running Python script with subprocess on Windows

Tim Golden mail at timgolden.me.uk
Wed May 28 15:46:25 EDT 2014


On 28/05/2014 06:08, Tim Golden wrote:
> On 28/05/2014 00:01, ps16thypresenceisfullnessofjoy at gmail.com wrote:
>
>> I want users to be able to enter paths in the XML file exactly the
>> way they would be entered in a Windows shortcut. Since it is possible
>> to make a Windows shortcut for path-to-script.py without the
>> python.exe in front of it and have it open in its own command prompt,
>> I want to be able to do the same thing in my XML file, but this is
>> what I cannot figure out.
>
> Anything done through shortcuts is making use of the Windows Shell API.
> To mimic that behaviour, you could try using that; in this case,
> ShellExecute[Ex]. For simple purposes, this is exposed in Python as
> os.startfile. If you need more control, you'd have to use the API call
> directly, either via ctypes or via the pywin32 libraries under the
> win32com.shell package.
>
> To mimic the behaviour exactly (if that is a requirement), you could
> actually create a temporary shortcut with the desired information and
> invoke it via os.startfile.
>
> I haven't followed the thread (and I'm offline at the moment) so I'll
> wait until I've seen it before I comment on the shlex.split / \\ dance
> above. On the surface, though, I'm not sure what it's achieving. [All
> right, I didn't wait :)].

I've just read the original post. My answer above isn't quite on the 
nail (although it might still be useful). If you're prepared to use the 
pywin32 libraries, then you could use win32api.FindExecutable to provide 
a first argument to the Popen constructor, followed by the others in 
your <app/> data. Something like this:

<code>
import subprocess
import win32api

# ...
for app_path in app_paths:
     args = ... split ...
     _, exe = win32api.FindExecutable(args[0])
     if exe != os.path.abspath(args[0]):
         args = [exe] + args
     subprocess.call(args)

</code>

As to the shlex dance, I *think* you're trying to break the command line 
up, expand any env vars, and then pass it along to Popen as above?
If your <app/> data were formatted as though for a Windows command-line, 
ie with the paths double-quoted if they contain spaces, then shlex 
should do the right thing by it without any further messing around.

So, if this example:

<app name="LibreOffice Writer">%ProgramFiles%\LibreOffice 
4\program\swriter.exe "C:\Users\Timothy\Documents\myfile.odt"</app>

were instead:

<app name="LibreOffice Writer">"%ProgramFiles%\LibreOffice 
4\program\swriter.exe" "C:\Users\Timothy\Documents\myfile.odt"</app>

then the shlex dance would just be:

args = [os.path.expandvars(i) for i in shlex.split(app_path)]

Although, assuming associations were set up in the usual way, the code I 
outlined above to use FindExecutable would cope with this without the 
need to specify the swriter.exe. As would the os.startfile approach I 
suggested earlier.

TJG



More information about the Python-list mailing list