我在使用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)