Skip to content

Instantly share code, notes, and snippets.

@drmalex07
Created April 12, 2014 20:08
Show Gist options
  • Save drmalex07/10554232 to your computer and use it in GitHub Desktop.
Save drmalex07/10554232 to your computer and use it in GitHub Desktop.
An example Windows service implemented with pywin32 wrappers. #python #windows-service #pywin32
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import time
import logging
logging.basicConfig(
filename = 'c:\\Temp\\hello-service.log',
level = logging.DEBUG,
format = '[helloworld-service] %(levelname)-7.7s %(message)s'
)
class HelloWorldSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "HelloWorld-Service"
_svc_display_name_ = "HelloWorld Service"
def __init__(self,args):
win32serviceutil.ServiceFramework.__init__(self,args)
self.stop_event = win32event.CreateEvent(None,0,0,None)
socket.setdefaulttimeout(60)
self.stop_requested = False
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.stop_event)
logging.info('Stopping service ...')
self.stop_requested = True
def SvcDoRun(self):
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,'')
)
self.main()
def main(self):
logging.info(' ** Hello PyWin32 World ** ')
# Simulate a main loop
for i in range(0,50):
if self.stop_requested:
logging.info('A stop signal was received: Breaking main loop ...')
break
time.sleep(5)
logging.info("Hello at %s" % time.ctime())
return
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(HelloWorldSvc)
@TheCDC
Copy link

TheCDC commented Apr 14, 2018

For future googlers finding this snippet, I had a heck of a time figuring out how to avoid the dreaded 1053 error when trying to start the service (from an executable compiled with pyinstaller).

This snippet appears to be missing the part that actually invokes the main() of the service class when the Windows Service framework runs the executable.

This tutorial is more complete:
https://www.codeproject.com/Articles/1115336/Using-Python-to-Make-a-Windows-Service

The difference is going from this:

if __name__ == '__main__':
win32serviceutil.HandleCommandLine(HelloWorldSvc)

to this

if __name__ == '__main__':
    if len(sys.argv) == 1:
        servicemanager.Initialize()
        servicemanager.PrepareToHostSingle(HelloWorldSvc)
        servicemanager.StartServiceCtrlDispatcher()
    else:
        win32serviceutil.HandleCommandLine(HelloWorldSvc)

This works because when the Service executes all it does is run the executable with no args. if len(sys.argv) == 1: checks how many command line args were supplied so it knows whether it's being run by the user with args such as install or otherwise being run as a service.

I hope this helps. Good luck!

@gurunadhd
Copy link

I used command below to create the service successfullt.
sc create binpath= "C:\Python27\Python.exe " DisplayName= "" start= auto

@vlzx
Copy link

vlzx commented Apr 30, 2020

The difference is going from this:

if __name__ == '__main__':
win32serviceutil.HandleCommandLine(HelloWorldSvc)

to this

if __name__ == '__main__':
    if len(sys.argv) == 1:
        servicemanager.Initialize()
        servicemanager.PrepareToHostSingle(HelloWorldSvc)
        servicemanager.StartServiceCtrlDispatcher()
    else:
        win32serviceutil.HandleCommandLine(HelloWorldSvc)

This works because when the Service executes all it does is run the executable with no args. if len(sys.argv) == 1: checks how many command line args were supplied so it knows whether it's being run by the user with args such as install or otherwise being run as a service.

I hope this helps. Good luck!

Thanks! You saved my day.

@PradeepMaharana
Copy link

I created windows service on python and it's running properly.But when when I am trying stop or abort service in between , it giving error 1053. What can be the solution to stop the running service

@krusli
Copy link

krusli commented Jun 9, 2022

For anyone else encountering a 1053 error with pyinstaller, it is also worth checking for other errors not necessarily related to the answer above.

In my case, turns out my program has relative paths for config files, etc.

Windows Services set C:\Windows\system32 as the working directory for the application.

This answer for Determining application path in a Python EXE generated by pyInstaller along with a os.chdir to change working directory worked for me:

# NOTE: for a --onefile executable, the path to the application is given by application_path = os.path.dirname(sys.executable) –
application_path = os.path.dirname(sys.executable)

# print(os.getcwd())  # will be C:\Windows\System32 when run as a service
# print('application_path ' + str(application_path))

# Change working directory to application path
os.chdir(application_path)

@DiegoLugo
Copy link

For anyone else encountering a 1053 error with pyinstaller, it is also worth checking for other errors not necessarily related to the answer above.

In my case, turns out my program has relative paths for config files, etc.

Windows Services set C:\Windows\system32 as the working directory for the application.

This answer for Determining application path in a Python EXE generated by pyInstaller along with a os.chdir to change working directory worked for me:

# NOTE: for a --onefile executable, the path to the application is given by application_path = os.path.dirname(sys.executable) –
application_path = os.path.dirname(sys.executable)

# print(os.getcwd())  # will be C:\Windows\System32 when run as a service
# print('application_path ' + str(application_path))

# Change working directory to application path
os.chdir(application_path)

How do you use it in the .py file?

@yang-shuaijun
Copy link

I wrote alike program.
SERVICE_NAME: BBA Log mask
DISPLAY_NAME: BBA Log mask
TYPE : 10 WIN32_OWN_PROCESS
STATE : 2 START_PENDING
(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x1388
It was able to start.
but it wansn't able to stop.
I didn't know the reason.

@simbullar
Copy link

For anyone else encountering a 1053 error with pyinstaller, it is also worth checking for other errors not necessarily related to the answer above.

In my case, turns out my program has relative paths for config files, etc.

Windows Services set C:\Windows\system32 as the working directory for the application.

This answer for Determining application path in a Python EXE generated by pyInstaller along with a os.chdir to change working directory worked for me:

# NOTE: for a --onefile executable, the path to the application is given by application_path = os.path.dirname(sys.executable) –
application_path = os.path.dirname(sys.executable)

# print(os.getcwd())  # will be C:\Windows\System32 when run as a service
# print('application_path ' + str(application_path))

# Change working directory to application path
os.chdir(application_path)

why changig dir if you can os.path.join? that would be a little be faster for optimization

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment