Subprocess Popen not working with pythonw.exe
Question: I want to be able to get the contents of stdout and stderr when I run the
following script on windows using pythonw.exe:

    
    
    import subprocess
    import sys
    import os
    import string
    import time
    
    tmpdir = 'c:/temp'
    cmd = 'dir c:'
    
    tmpfile = "tmp_%f" % (time.time())
    tmpfile = os.path.normpath(os.path.join(tmpdir,tmpfile))
    tmpfile2 = tmpfile+".bat"
    tmpfile3 = tmpfile+".txt"
    
    fa = open(tmpfile2,'w')
    fa.write("@ECHO OFF > NUL\n")
    fa.write('call '+cmd+"\n")
    fa.close()
    
    wcmd = []
    wcmd.append(tmpfile2)
    
    startupinfo = subprocess.STARTUPINFO()
    startupinfo.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW
    
    fb = open(tmpfile3,'w')
    fb.write("\n")
    fb.write(tmpfile2+"\n")
    
    try:
        procval = subprocess.Popen(wcmd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
        fb.write(str(procval)+"\n")
        fb.write("Sucess")
        fb.close()
    except:
        fb.write(str(procval)+"\n")
        fb.write("Failure")
        fb.close()
    

When I execute it using python.exe I get the expected output. When I run it
using pythonw.exe I end up on the exception side. If I run the popen with just
the command and the startupinfo flags the command will successfully complete
but no access to the data in the child processs. Everything that I read stated
that this should work but must be missing something. Any help would be greatly
appreciated.

Thanks, Randy


Answer: This is possibly a bug when using pythonw.exe

pythonw.exe starts a daemon process which doesn't have the normal access to
the standard file descriptors. The only thing you would need to do in your
script is to specifically set the 3rd fd for stdin:

    
    
    p = subprocess.Popen(wcmd,
                         startupinfo=startupinfo,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT,
                         stdin=subprocess.PIPE)
    procval = p.communicate()
    

