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服务?

Python无法在工作计算机上找到已安装的模块-Windows OS

python怎么操作windows服务?

如何结束作为 os.system() 调用运行的线程(Python)

如何在不脱离控制台的情况下在 Windows 中的 Python 中执行 os.execv()?