使用从 pyinstaller 生成的 python exe 来创建 Windows 服务时出现错误。该错误消息可能是无害的,并且似乎不会影响服务的运行,但我不确定幕后是否还有其他问题。我正在使用 pywin32 库将应用程序安装为 Windows 服务。我应该注意,从 python 脚本本身安装时,我没有收到此错误,使用 pywin32 中的 PythonService.exe,仅来自使用 pyinstaller 生成的可执行文件。
使用 pyinstaller 时,我可以从我的 windows 服务代码生成 exe 并安装它,没问题。我也可以启动服务,没问题。我什至可以停止服务并且应用程序似乎正常关闭。但是,一旦我启动了停止,我在运行 win32traceutil.py 时在控制台上收到以下错误:
"Exception KeyError: KeyError(2244,) in <module 'threading' from '2\build\pyi.win32\agentservice\outPYZ1.pyz/threading'> ignored"
没有错误记录到事件日志中。我已经能够将其追溯到 python 日志记录模块。简单地导入日志模块似乎会导致我的问题。注释掉导入可以消除错误。对我来说似乎很清楚这是导致问题的原因,但我觉得奇怪的是 pyinstaller 会遇到标准库中的模块问题。有没有其他人遇到过这个?
我正在运行 Python 2.6.6、Pyinstaller 1.5.1、Pywin32 的 Build 217。我在 Windows XP 上。
以及我的代码的精简版本:
import win32service
import win32serviceutil
import win32event
import win32evtlogutil
import win32traceutil
import servicemanager
import sys
import os
import time
class myservice(win32serviceutil.ServiceFramework):
_svc_name_ = "5"
_svc_display_name_ = "5"
_svc_deps_ = ["EventLog"]
def __init__(self, args):
self.isAlive = True
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
def event_log(self, msg):
servicemanager.LogInfoMsg(str(msg))
def SvcStop(self):
# tell Service Manager we are trying to stop (required)
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
print "svcstop: stopping service, setting event"
# set the event to call
win32event.SetEvent(self.hWaitStop)
print "svcstop: ending svcstop"
def SvcDoRun(self):
print "we are starting the service..."
self.event_log("Starting %s" % self._svc_name_)
############ IF LOGGING IS COMMENTED OUT, THE ERROR GOES AWAY################
import logging
print "svcdorun: waiting for object"
win32event.WaitForSingleObject(self.hWaitStop,win32event.INFINITE)
print "svcdorun: return from function"
if __name__ == '__main__':
if len(sys.argv)==1:
import win32traceutil
print "service is starting..."
#servicemanager.Initialize()
servicemanager.Initialize('backup service', None)
servicemanager.PrepareToHostSingle(myservice)
# Now ask the service manager to fire things up for us...
servicemanager.StartServiceCtrlDispatcher()
print "service done!"
else:
win32serviceutil.HandleCommandLine(myservice)