Any more it seems that virtually all the code I write on the windows platform
ends up being a windows service. It's just the nature of the kind of work I do:
the underappreciated guts that sit far beneath the software that users directly
interact with. Obviously windows services are typically written in mainstream
.Net languages like C# or VB these days but it's also easy if not easier
to do in Python.
Requirements
The Code
Once your Python environment meets the requirements outlined above you're ready to write your service. All you have to do is write an extension of the ServiceFramework class that overrides the SvcDoRun and SvcStop methods. As you can guess SvcDoRun performs the core logic of your service and SvcStop shuts it down.
I've created a sample service below that simply writes some text to a file every five seconds until the service is stopped. Note that this example uses windows signal events to trigger service shutdown via the CreateEvent, WaitForSingleObject and SetEvent windows API calls. Thank you Windows Extensions!
import win32service
import win32serviceutil
import win32event
class PySvc(win32serviceutil.ServiceFramework):
# you can NET START/STOP the service by the following name
_svc_name_ = "PySvc"
# this text shows up as the service name in the Service
# Control Manager (SCM)
_svc_display_name_ = "Python Test Service"
# this text shows up as the description in the SCM
_svc_description_ = "This service writes stuff to a file"
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self,args)
# create an event to listen for stop requests on
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
# core logic of the service
def SvcDoRun(self):
import servicemanager
f = open('test.dat', 'w+')
rc = None
# if the stop event hasn't been fired keep looping
while rc != win32event.WAIT_OBJECT_0:
f.write('TEST DATA\n')
f.flush()
# block for 5 seconds and listen for a stop event
rc = win32event.WaitForSingleObject(self.hWaitStop, 5000)
f.write('SHUTTING DOWN\n')
f.close()
# called when we're being shut down
def SvcStop(self):
# tell the SCM we're shutting down
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
# fire the stop event
win32event.SetEvent(self.hWaitStop)
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(PySvc)
Service Installation
Now that the service itself is written we can install it as follows:
C:\Dev\Projects\PySvc> python.exe .\PySvc.py install
Service Control
That's it! The service can now be started from the command line by
C:\Dev\Projects\PySvc> NET START PySvc
or from the Service Control Manager
Mon Nov 02 2009 20:11:00 GMT+0000 (UTC)
Comment Feed -
Permalink
After the service is started the test.dat will end up in the same directory as PySvc.py.by chrisumbel on Thu Nov 12 2009 09:11:00 GMT+0000 (UTC)