Python Windows Service Pyinstaller Executables Error 1053
Solution 1:
Try changing the last few lines to
if__name__== '__main__':
iflen(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(Service)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(Service)
Solution 2:
MrTorture had the key to this answer, but I'd like to build upon that here. Something critical to note is that even when using the win32serviceutil functions to manage the service programmatically (vs installing, starting, etc. via the command prompt), you must include the entry point command line dispatch for this to work in a standalone context (i.e. when building an exe with pyinstaller or py2exe). If you don't, Windows will not be able to start the service. You'll get the dreaded 1053 error!
In addition to that, note that if you are creating a service as part of a larger project, you will need to build an exe dedicated to the service. You cannot run it as a sub component within a larger exe (at least I didn't have luck trying to!). I've included my install function to demonstrate that.
Again, when using .py scripts, managed via pythonservice.exe, neither of these issues are present, these are only concerns for standalone exes.
Here are some INCOMPLETE snippets of my functional code, but they might save you a lot of trouble:
SUCCESS = winerror.ERROR_SUCCESS
FAILURE = -1classWinServiceManager():
# pass the class, not an instance of it!def__init__( self, serviceClass, serviceExeName=None):
self.serviceClass_ = serviceClass
# Added for pyInstaller v3
self.serviceExeName_ = serviceExeName
defisStandAloneContext( self ) :
# Changed for pyInstaller v3#return sys.argv[0].endswith( ".exe" ) returnnot( sys.argv[0].endswith( ".py" ) )
defdispatch( self ):
if self.isStandAloneContext() :
servicemanager.Initialize()
servicemanager.PrepareToHostSingle( self.serviceClass_ )
servicemanager.Initialize( self.serviceClass_._svc_name_,
os.path.abspath( servicemanager.__file__ ) )
servicemanager.StartServiceCtrlDispatcher()
else :
win32api.SetConsoleCtrlHandler(lambda x: True, True)
win32serviceutil.HandleCommandLine( self.serviceClass_ )
# Service management functions# # Note: all of these functions return:# SUCCESS when explicitly successful# FAILURE when explicitly not successful at their specific purpose# winerror.XXXXXX when win32service (or related class) # throws an error of that nature#------------------------------------------------------------------------# Note: an "auto start" service is not auto started upon installation!# To install and start simultaneously, use start( autoInstall=True ).# That performs both actions for manual start services as well.definstall( self ):
win32api.SetConsoleCtrlHandler(lambda x: True, True)
result = self.verifyInstall()
if result == SUCCESS or result != FAILURE: return result
thisExePath = os.path.realpath( sys.argv[0] )
thisExeDir = os.path.dirname( thisExePath )
# Changed for pyInstaller v3 - which now incorrectly reports the calling exe# as the serviceModPath (v2 worked correctly!)if self.isStandAloneContext() :
serviceModPath = self.serviceExeName_
else :
serviceModPath = sys.modules[ self.serviceClass_.__module__ ].__file__
serviceModPath = os.path.splitext(os.path.abspath( serviceModPath ))[0]
serviceClassPath = "%s.%s" % ( serviceModPath, self.serviceClass_.__name__ )
self.serviceClass_._svc_reg_class_ = serviceClassPath
# Note: in a "stand alone context", a dedicated service exe is expected # within this directory (important for cases where a separate master exe # is managing services).
serviceExePath = (serviceModPath + ".exe") if self.isStandAloneContext() elseNone
isAutoStart = self.serviceClass_._svc_is_auto_start_
startOpt = (win32service.SERVICE_AUTO_START if isAutoStart else
win32service.SERVICE_DEMAND_START)
try :
win32serviceutil.InstallService(
pythonClassString = self.serviceClass_._svc_reg_class_,
serviceName = self.serviceClass_._svc_name_,
displayName = self.serviceClass_._svc_display_name_,
description = self.serviceClass_._svc_description_,
exeName = serviceExePath,
startType = startOpt
)
except win32service.error as e: return e[0]
except Exception as e: raise e
win32serviceutil.SetServiceCustomOption(
self.serviceClass_._svc_name_, WORKING_DIR_OPT_NAME, thisExeDir )
for i inrange( 0, MAX_STATUS_CHANGE_CHECKS ) :
result = self.verifyInstall()
if result == SUCCESS: return SUCCESS
time.sleep( STATUS_CHANGE_CHECK_DELAY )
return result
In the module where you define your service (derived from win32serviceutil.ServiceFramework), include this at the end of it:
if__name__== "__main__":
WinServiceManager( MyServiceClass, "MyServiceBinary.exe" ).dispatch()
Post a Comment for "Python Windows Service Pyinstaller Executables Error 1053"