Python Windows 服务 pyinstaller 可执行文件错误 1053 [英] Python Windows service pyinstaller executables error 1053
问题描述
我用 python 编写了一个 Windows 服务.如果我从命令提示符运行我的脚本
I have written a Windows service in python. If I run my script from the command prompt
python runService.py
当我这样做时,服务会正确安装并启动.我一直在尝试使用 pyinstaller 创建一个可执行文件,因为我在 py2exe 上看到了同样的问题.当我运行 .exe 时,服务会安装但未启动,并且出现以下错误
When I do this the service installs and starts correctly. I have been trying to create an executable using pyinstaller because i've seen the same issue with py2exe. When I run the .exe the service installs but does not start and I get the following error
error 1053 the service did not respond to the start or control request in a timely fashion
我看到很多人都遇到过这个问题,但我似乎找不到关于如何解决这个问题的明确答案.
I have seen that many people have had this issue but I can't seem to find a definitive answer as to how to fix this.
winservice.py
from os.path import splitext, abspath
from sys import modules, executable
from time import *
import win32serviceutil
import win32service
import win32event
import win32api
class Service(win32serviceutil.ServiceFramework):
_svc_name_ = '_unNamed'
_svc_display_name_ = '_Service Template'
_svc_description_ = '_Description template'
def __init__(self, *args):
win32serviceutil.ServiceFramework.__init__(self, *args)
self.log('init')
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
#logs into the system event log
def log(self, msg):
import servicemanager
servicemanager.LogInfoMsg(str(msg))
def sleep(self, minute):
win32api.Sleep((minute*1000), True)
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
try:
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.log('start')
self.start()
self.log('wait')
win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
self.log('done')
except Exception, x:
self.log('Exception : %s' % x)
self.SvcStop()
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
#self.log('stopping')
self.stop()
#self.log('stopped')
win32event.SetEvent(self.stop_event)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
# to be overridden
def start(self): pass
# to be overridden
def stop(self): pass
def instart(cls, name, description, display_name=None, stay_alive=True):
''' Install and Start (auto) a Service
cls : the class (derived from Service) that implement the Service
name : Service name
display_name : the name displayed in the service manager
decription: the description
stay_alive : Service will stop on logout if False
'''
cls._svc_name_ = name
cls._svc_display_name_ = display_name or name
cls._svc_desciption_ = description
try:
module_path=modules[cls.__module__].__file__
except AttributeError:
module_path=executable
module_file = splitext(abspath(module_path))[0]
cls._svc_reg_class_ = '%s.%s' % (module_file, cls.__name__)
if stay_alive: win32api.SetConsoleCtrlHandler(lambda x: True, True)
try:
win32serviceutil.InstallService(
cls._svc_reg_class_,
cls._svc_name_,
cls._svc_display_name_,
startType = win32service.SERVICE_AUTO_START,
description = cls._svc_desciption_
)
print 'Install ok'
win32serviceutil.StartService(
cls._svc_name_
)
print 'Start ok'
except Exception, x:
print str(x)
更新
我使用 py2exe 解决了这个问题,但同样的更改也适用于 pyinstaller.我没有时间亲自检查这个.
I resolved this issue by using py2exe but the same changes may work for pyinstaller too. I haven't had time to check this out myself.
我不得不删除instart 功能.下面是我的 winservice.py 现在的读取方式.
I had to remove the instart function. Below is how my winservice.py reads now.
winservice_py2exe.py
from os.path import splitext, abspath
from sys import modules, executable
from time import *
import win32serviceutil
import win32service
import win32event
import win32api
class Service(win32serviceutil.ServiceFramework):
_svc_name_ = 'actualServiceName' #here is now the name you would input as an arg for instart
_svc_display_name_ = 'actualDisplayName' #arg for instart
_svc_description_ = 'actualDescription'# arg from instart
def __init__(self, *args):
win32serviceutil.ServiceFramework.__init__(self, *args)
self.log('init')
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
#logs into the system event log
def log(self, msg):
import servicemanager
servicemanager.LogInfoMsg(str(msg))
def sleep(self, minute):
win32api.Sleep((minute*1000), True)
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
try:
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.log('start')
self.start()
self.log('wait')
win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
self.log('done')
except Exception, x:
self.log('Exception : %s' % x)
self.SvcStop()
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
#self.log('stopping')
self.stop()
#self.log('stopped')
win32event.SetEvent(self.stop_event)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
# to be overridden
def start(self): pass
# to be overridden
def stop(self): pass
if __name__ == '__main__':
# Note that this code will not be run in the 'frozen' exe-file!!!
win32serviceutil.HandleCommandLine(VidiagService) #added from example included with py2exe
下面是我与 py2exe 一起使用的 setup.py 文件.这取自 py2exe 安装中包含的示例:
Below is the setup.py file i used with py2exe. This was taken from the example included with the py2exe installation:
setup.py
from distutils.core import setup
import py2exe
import sys
if len(sys.argv) == 1:
sys.argv.append("py2exe")
sys.argv.append("-q")
class Target:
def __init__(self, **kw):
self.__dict__.update(kw)
# for the versioninfo resources
self.version = "0.5.0"
self.company_name = "No Company"
self.copyright = "no copyright"
self.name = "py2exe sample files"
myservice = Target(
# used for the versioninfo resource
description = "A sample Windows NT service",
# what to build. For a service, the module name (not the
# filename) must be specified!
modules = ["winservice_py2exe"]
)
setup(
options = {"py2exe": {"typelibs":
# typelib for WMI
[('{565783C6-CB41-11D1-8B02-00600806D9B6}', 0, 1, 2)],
# create a compressed zip archive
"compressed": 1,
"optimize": 2}},
# The lib directory contains everything except the executables and the python dll.
# Can include a subdirectory name.
zipfile = "lib/shared.zip",
service = [myservice]
)
创建 exe 后,您可以使用以下命令从命令安装服务
once you create the exe you can install the service from command using the following command
winservice_py2exe.exe -install
然后启动您可以使用的服务:
then to start the service you can use:
net start aTest
或来自 Windows 服务管理器.所有其他 Windows 命令行功能现在可在该服务以及 Windows 服务管理器中使用.
or from windows service manager. All other windows command line functionality now works on the service as well as from windows service manager.
推荐答案
尝试将最后几行更改为
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(Service)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(Service)
这篇关于Python Windows 服务 pyinstaller 可执行文件错误 1053的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!