Friday, February 4, 2011

Can I run a Python script as a service (in Windows)? How?

I am sketching the architecture for a set of programs that share various interrelated objects stored in a database. I want one of the programs to act as a service which provides a higher level interface for operations on these objects, and the other programs to access the objects through that service.

I am currently aiming for Python and the Django framework as the technologies to implement that service with. I'm pretty sure I figure how to daemonize the Python program in Linux. However, it is an optional spec item that the system should support Windows. I have little experience with Windows programming and no experience at all with Windows services.

Can I run Python programs as a Windows service (i. e. run it automatically without user login)? I won't necessarily have to implement this part, but I need a rough idea how it would be done in order to decide whether to design along these lines.

Edit: Thanks for all the answers so far, they are quite comprehensive. I would like to know one more thing: How is Windows aware of my service? Can I manage it with the native Windows utilities? Basically, what is the equivalent of putting a start/stop script in /etc/init.d?

  • You will need some "windows service wrapper", you could write it yourself or just check out srvany.exe. Here is some tutorial how to use it.

  • Yes you can. I do it using the pythoncom libraries that come included with ActivePython

    This is a basic squeleton for a simple service:

    import pythoncom
    import win32serviceutil
    import win32service
    import win32event
    import servicemanager
    
    
    class AppServerSvc (win32serviceutil.ServiceFramework):
        _svc_name_ = "TestService"
        _svc_display_name_ = "Test Service"
    
        def __init__(self,args):
            win32serviceutil.ServiceFramework.__init__(self,args)
            self.hWaitStop = win32event.CreateEvent(None,0,0,None)
            socket.setdefaulttimeout(60)
    
        def SvcStop(self):
            self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
            win32event.SetEvent(self.hWaitStop)
    
        def SvcDoRun(self):
            servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                                  servicemanager.PYS_SERVICE_STARTED,
                                  (self._svc_name_,''))
            self.main()
    
        def main(self):
            pass
    
    if __name__ == '__main__':
        win32serviceutil.HandleCommandLine(AppServerSvc)
    

    Your code would go in the main() method, usually with some kind of infinite loop that might be interrumped by checking a flag, that you set in the SvcStop method

    Kit : After coding this, how do I tell Windows to run this as a service?
    Ricardo Reyes : @Kit: run your script with the from the command line with the parameter "install". Then you'll be able to see your application in Windows' Services list, where you can start it, stop it, or set it to start automatically
    Kit : `python my_script_as_service.py install` ?
  • This article on Codeproject contains a program that can start other non-service applications as if they were a service.

    Otherwise you must design a real service application which is different from a normal windows application.

  • see Python Win Service

    From dugres
  • Or use Tim Golden's WMI module for Python: http://timgolden.me.uk/python/wmi/tutorial.html#creating-wmi-objects

    From Tscott4

0 comments:

Post a Comment