Search code examples
pythonwindowssubprocesscase-sensitive

Why does providing an environment to my Python subprocess cause it to abort?


I am attempting to run a subprocess through Python of an executable developed by my company; let's call it prog.exe. I can run this command just fine on from CMD; I can run it just fine through subprocess; but if I try to pass env to subprocess, I get an error:

C:\Users\me> prog.exe -h
prog V1.2.2 (Build 09-07-2016.12.52)
more dummy help text...
C:\Users\me> python
Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> import os
>>> subprocess.Popen("prog.exe -h").wait()
prog V1.2.2 (Build 09-07-2016.12.52)
more dummy help text...
0
>>> 
>>> subprocess.Popen("prog.exe -h", env=os.environ).wait()

After executing that command, the following dialog opens informing me that "prog.exe has stopped working" and "Windows is checking for a solution to the problem...":

prog.exe has stopped working

which turns into "A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available.":

prog.exe has truly stopped working

When I close that dialog, the subprocess exits with an error:

255
>>>

What is going on? I thought that os.environ is essentially passed as env to subprocess if I do not specify env. So why when I specify it does it cause my program to die?

I have tried Python 3.5 and Python 2.7 with same results.


Solution

  • As described in an older SO post, the os.environ keys are stored/accessed in a case insensitive manner. nt.environ preserves the case of the environment variables as passed into the Python process.

    In this case, prog.exe is evidently accessing environment variables in a case sensitive manner, thus it requires the original mixed-case environment to be passed in.

    Using nt.environ rather than os.environ resolves the issue:

    >>> import nt
    >>> subprocess.Popen("prog.exe -h", env=nt.environ).wait()
    prog V1.2.2 (Build 09-07-2016.12.52)
    more dummy help text...
    0
    >>>