Python 作为 Windows 服务运行:OSError: [WinError 6] 句柄无效
Posted
技术标签:
【中文标题】Python 作为 Windows 服务运行:OSError: [WinError 6] 句柄无效【英文标题】:Python running as Windows Service: OSError: [WinError 6] The handle is invalid 【发布时间】:2017-02-27 18:16:09 【问题描述】:我有一个 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
【问题讨论】:
【参考方案1】:subprocess.py
中的第 1117 行是:
p2cread = _winapi.GetStdHandle(_winapi.STD_INPUT_HANDLE)
这让我怀疑服务进程没有与之关联的 STDIN (TBC)
通过将文件或空设备作为标准输入参数提供给popen
,可以避免这种麻烦的代码。
在 Python 3.x 中,您可以简单地传递 stdin=subprocess.DEVNULL
。例如
subprocess.Popen( args=[self.exec_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.DEVNULL)
在 Python 2.x 中,您需要将文件处理程序设为 null,然后将其传递给 popen:
devnull = open(os.devnull, 'wb')
subprocess.Popen( args=[self.exec_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=devnull)
【讨论】:
服务可执行文件(例如pythonservice.exe)以分离方式运行(即不附加到conhost.exe的实例),在这种情况下GetStdHandle
应该返回NULL
,而不是INVALID_HANDLE_VALUE
。
通过 pythonw.exe 运行时经常会出现类似的错误。在 Windows 8 之前,pythonw.exe 进程在其标准句柄中具有控制台句柄值,但它们是无效的,因为没有附加控制台。子进程尝试在无效句柄上调用 DuplicateHandle
时引发错误。
好的,我想我这里有最前卫的情况,所以我不确定其他人会找到它 - 我的脚本已使用 PyInstaller 编译成独立的 .exe。该脚本不是实际的服务 - C#/.net 应用程序是分叉独立 .exe 的服务。该服务具有独立模式,当以桌面用户身份执行时,可以按预期工作。
subprocess.run( cmd, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
在嵌套(subprocess.Popen、Windows 应用程序、通过 DLL 的 python)中运行时,在 Python 3.6 中会出现类似的错误。添加stdin = subprocess.DEVNULL
修复它。
@SmitJohnth 看起来有一个计数选项。将其设置为1
并循环。【参考方案2】:
加stdin=subprocess.PIPE
赞:
with subprocess.Popen( args=[self.exec_path], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT) as proc:
【讨论】:
以上是关于Python 作为 Windows 服务运行:OSError: [WinError 6] 句柄无效的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Windows 中将 Python 脚本作为服务运行?
Python无法在工作计算机上找到已安装的模块-Windows OS