According to the docs, CreateProcess can be passed an executable name as first argument, or a command line as a second argument (from which the executable name will be extracted).
If you pass an executable name, the docs say PATH
won't be searched.
if you pass a command line instead, the first token is extracted to be used
as the executable name and PATH
is supposed to be searched.
In my case, though, my call to CreateProcess
---with a command line only and
with a modified environment--- doesn't find the sought executable. It only
succeeds if I precede the command line with cmd.exe /c
(I understand why
it works this way).
For completeness, I'm not actually using the Windows API directly, but
subprocess.Popen
in Python, although I think I've narrowed down the problem
to the above circumstances. With shell = True
, the right environment is
picked up; with shell = False
(my desired way of creating the subprocess),
the call fails to locate my executable. The executable is a standalone exe, not an intrinsic command of cmd.exe.
Can someone please tell my what I'm doing wrong here or where's my misunderstanding?
Example code:
from subprocess import Popen
import os, sys
exe = "wc.exe" # No other wc.exe on the PATH
env = os.environ.copy()
new_path = os.path.expandvars(r"%HOMEDRIVE%%HOMEPATH%\SmallApps\GnuWin32\bin;%PATH%")
env["PATH"] = os.path.expandvars(new_path).encode(sys.getfilesystemencoding())
Popen(
args=[exe, "*.*"],
env=env,
# shell=True # Works if you uncomment this line.
)
You need to modify the environment of the current process if you want
CreateProcess
to see it. Currently, the subshell (whether included in the command line or requested viashell=True
) is seeing your modified environment, but the direct invocation ofCreateProcess
is not.Thought of checking MSDN? CreateProcess documentation.
To quote one part of it:
If I'm reading your question right, it sounds like you have an application named
wc.exe
in the folder that%HOMEDRIVE%%HOMEPATH%\SmallApps\GnuWin32\bin
maps to. If that is the case, you would do better to set exe to the expanded version of%HOMEDRIVE%%HOMEPATH%\SmallApps\GnuWin32\bin\wc.exe
. Since this path and executable name may end up containing spaces, it wouldn't hurt to wrap it in quotes as well.In short, don't rely on the path search. Not only is it prone to errors, it's also a potential security hole.