我已經在python中編寫了Windows服務。如果我從命令提示符運行我的腳本Python Windows服務pyinstaller可執行文件錯誤1053
python runService.py
當我這樣做時,服務將安裝並正確啓動。我一直在嘗試使用pyinstaller創建一個可執行文件,因爲我已經看到了與py2exe相同的問題。當我運行的服務安裝,但沒有啓動的.exe和我收到以下錯誤
error 1053 the service did not respond to the start or control request in a timely fashion
我見過很多人都有過這樣的問題,但我似乎無法找到一個明確的答案,如何解決這個問題。
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)
UPDATE
我使用py2exe解決了這個問題,但同樣的變化可能對pyinstaller工作了。我沒有時間自己檢查一下。
我不得不刪除instart函數。以下是我的winservice.py現在讀取。
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
下面是setup.py文件我py2exe使用。這是從包括在py2exe安裝例如採取:
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文件,你可以使用下面的命令
winservice_py2exe.exe -install
安裝從命令的服務
然後啓動您可以使用的服務:
net start aTest
或來自windows服務管理器。所有其他Windows命令行功能現在可以在服務以及Windows服務管理器上運行。
這對我使用pyinstaller工作。但是,爲什麼它沒有工作,如果當安裝爲python文件? – enthus1ast 2014-10-27 16:36:19
因爲PythonService.exe會照顧到這一點。 – MrTorture 2014-10-28 17:28:14
OP你應該接受這個答案 – arminb 2015-01-27 12:56:21