Python running as Windows Service: OSError: [WinError 6] The handle is invalid

22,711

Solution 1

Line 1117 in subprocess.py is:

p2cread = _winapi.GetStdHandle(_winapi.STD_INPUT_HANDLE)

which made me suspect that service processes do not have a STDIN associated with them (TBC)

This troublesome code can be avoided by supplying a file or null device as the stdin argument to popen.

In Python 3.x, you can simply pass stdin=subprocess.DEVNULL. E.g.

subprocess.Popen( args=[self.exec_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.DEVNULL)

In Python 2.x, you need to get a filehandler to null, then pass that to popen:

devnull = open(os.devnull, 'wb')
subprocess.Popen( args=[self.exec_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=devnull)

Solution 2

Add stdin=subprocess.PIPE like:

with subprocess.Popen( args=[self.exec_path], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT) as proc:
Share:
22,711

Related videos on Youtube

Alastair McCormack
Author by

Alastair McCormack

"If you can't explain it simply, you don't understand it well enough" - contested attribution Find me on Github: https://github.com/alastairmccormack

Updated on August 02, 2022

Comments

  • Alastair McCormack
    Alastair McCormack almost 2 years

    I have a Python script, which is running as a Windows Service. The script forks another process with:

    with subprocess.Popen( args=[self.exec_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as proc:
    

    which causes the following error:

    OSError: [WinError 6] The handle is invalid
       File "C:\Program Files (x86)\Python35-32\lib\subprocess.py", line 911, in __init__
       File "C:\Program Files (x86)\Python35-32\lib\subprocess.py", line 1117, in _get_handles
    
  • Eryk Sun
    Eryk Sun over 7 years
    Service executables (e.g. pythonservice.exe) are run detached (i.e. not attached to an instance of conhost.exe), in which case GetStdHandle should return NULL, not INVALID_HANDLE_VALUE.
  • Eryk Sun
    Eryk Sun over 7 years
    A similar error is common when running via pythonw.exe. Prior to Windows 8, a pythonw.exe process has console handle values in its standard handles, but they're invalid since there's no attached console. subprocess raises an error when it tries to call DuplicateHandle on the invalid handle.
  • Alastair McCormack
    Alastair McCormack over 7 years
    Ok, I think I have the edgiest of edge cases here, so I'm not sure anyone else will find it - My script has been compiled into a standalone .exe using PyInstaller. The script isn't the actual service - a C#/.net app is the service which forks the standalone .exe. The service has a standalone mode, which, when executed as a desktop user, works as expected.
  • user297500
    user297500 over 6 years
    Thanks for the help, I had a few dependency python packages which broke after configuring application to run as a Windows Service - same issue and workaround used to fix.
  • hardmooth
    hardmooth over 6 years
    similar error comes in Python 3.6 for subprocess.run( cmd, stdout = subprocess.PIPE, stderr = subprocess.PIPE) when running inside nested (subprocess.Popen, Windows Application, python via DLL). adding stdin = subprocess.DEVNULL fixed it.
  • Mathias Dolidon
    Mathias Dolidon over 5 years
    Ran into the same issue after I packaged a script with Pyinstaller. Using subprocess.DEVNULL did the trick. Big thanks !
  • Isquare1
    Isquare1 almost 4 years
    Stupid question, but you set stdin as DEVNULL in the original subprocesses module, or in the erroneous script that calls subprocesses ? If it is the first - can you tell me where to find it exactly? If it is the second - I tried adding it as keyword argument in the subprocess.Popen, as well as in the subprocess.call line (where the error actually happens), using kwargs['stdin'] = devnull, but it doesn't solve the problem. :(
  • Alastair McCormack
    Alastair McCormack almost 4 years
    @Isquare1 you only need to fix your code (or 3rd party code), not Python's codebase.
  • Smit Johnth
    Smit Johnth almost 3 years
    Dude, you saved me! Run on this problem like this: Popen(['ping', '192.168.0.1'], stdout=PIPE, stderr=PIPE). Seems you had to support stdin if you supported stdout and stderr.
  • Alastair McCormack
    Alastair McCormack almost 3 years
    Hey @SmitJohnth. Top tip, use native Python libraries, like pypi.org/project/icmplib, where you can. It's more powerful and you'll find it much easier to handle errors.
  • Smit Johnth
    Smit Johnth almost 3 years
    @AlastairMcCormack Can it report while working? The call simply blocked for me.
  • Alastair McCormack
    Alastair McCormack almost 3 years
    @SmitJohnth looks like it has a count option. Set it to 1 and loop.
  • Smit Johnth
    Smit Johnth almost 3 years
    @AlastairMcCormack well... I almost already written this using subprocess. And this lib requires root. I'll still need subprocess at some time.