作为Windows服务运行的Python:OSError:[WinError 6]句柄无效

作为Windows服务运行的Python:OSError:[WinError 6]句柄无效,python,windows,subprocess,Python,Windows,Subprocess,我有一个Python脚本,它作为Windows服务运行。该脚本使用以下内容派生另一个进程: with subprocess.Popen( args=[self.exec_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as proc: 这将导致以下错误: OSError: [WinError 6] The handle is invalid File "C:\Program Files (x86)\Python35-32\

我有一个Python脚本,它作为Windows服务运行。该脚本使用以下内容派生另一个进程:

with subprocess.Popen( args=[self.exec_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as proc:
这将导致以下错误:

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

subprocess.py
中的第1117行是:

p2cread = _winapi.GetStdHandle(_winapi.STD_INPUT_HANDLE)
这让我怀疑服务进程没有与之关联的STDIN(TBC)

通过将文件或空设备作为stdin参数提供给
popen
,可以避免这种麻烦的代码

Python3.x中,只需传递
stdin=subprocess.DEVNULL
。例如

subprocess.Popen( args=[self.exec_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.DEVNULL)
在Python 2.x中,需要将filehandler设置为null,然后将其传递给popen:

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

添加
stdin=subprocess.PIPE
类似:

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

服务可执行文件(例如pythonservice.exe)是独立运行的(即未连接到conhost.exe的实例),在这种情况下,
GetStdHandle
应返回
NULL
,而不是
无效的句柄值
。通过pythonw.exe运行时,类似错误很常见。在Windows 8之前,pythonw.exe进程的标准句柄中有控制台句柄值,但这些值无效,因为没有连接的控制台。子进程在尝试调用无效句柄上的
DuplicateHandle
时引发错误。好的,我认为我这里的边缘情况最为尖锐,因此我不确定其他人是否会找到它-我的脚本已使用PyInstaller编译成独立的.exe。脚本不是实际的服务-C#/.net应用程序是派生独立.exe的服务。该服务有一个独立模式,当作为桌面用户执行时,它会按预期工作。感谢您的帮助,我有一些依赖性python包,在将应用程序配置为作为Windows服务运行后,这些包出现了问题,这与用于修复的问题和解决方法相同。类似的错误出现在python 3.6 for
subprocess.run中(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
在嵌套(subprocess.Popen,Windows应用程序,python通过DLL)中运行时。添加
stdin=subprocess.DEVNULL
修复了它。