How do you run a Python script as a service in Windows?

后端 未结 13 1604
你的背包
你的背包 2020-11-22 02:18

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 prov

相关标签:
13条回答
  • 2020-11-22 02:31

    The simplest way to achieve this is to use native command sc.exe:

    sc create PythonApp binPath= "C:\Python34\Python.exe --C:\tmp\pythonscript.py"
    

    References:

    1. https://technet.microsoft.com/en-us/library/cc990289(v=ws.11).aspx
    2. When creating a service with sc.exe how to pass in context parameters?
    0 讨论(0)
  • 2020-11-22 02:31

    Step by step explanation how to make it work :

    1- First create a python file according to the basic skeleton mentioned above. And save it to a path for example : "c:\PythonFiles\AppServerSvc.py"

    import win32serviceutil
    import win32service
    import win32event
    import servicemanager
    import socket
    
    
    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):
            # Your business logic or call to any class should be here
            # this time it creates a text.txt and writes Test Service in a daily manner 
            f = open('C:\\test.txt', 'a')
            rc = None
            while rc != win32event.WAIT_OBJECT_0:
                f.write('Test Service  \n')
                f.flush()
                # block for 24*60*60 seconds and wait for a stop event
                # it is used for a one-day loop
                rc = win32event.WaitForSingleObject(self.hWaitStop, 24 * 60 * 60 * 1000)
            f.write('shut down \n')
            f.close()
    
    if __name__ == '__main__':
        win32serviceutil.HandleCommandLine(AppServerSvc)
    

    2 - On this step we should register our service.

    Run command prompt as administrator and type as:

    sc create TestService binpath= "C:\Python36\Python.exe c:\PythonFiles\AppServerSvc.py" DisplayName= "TestService" start= auto

    the first argument of binpath is the path of python.exe

    second argument of binpath is the path of your python file that we created already

    Don't miss that you should put one space after every "=" sign.

    Then if everything is ok, you should see

    [SC] CreateService SUCCESS

    Now your python service is installed as windows service now. You can see it in Service Manager and registry under :

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TestService

    3- Ok now. You can start your service on service manager.

    You can execute every python file that provides this service skeleton.

    0 讨论(0)
  • 2020-11-22 02:32

    There are a couple alternatives for installing as a service virtually any Windows executable.

    Method 1: Use instsrv and srvany from rktools.exe

    For Windows Home Server or Windows Server 2003 (works with WinXP too), the Windows Server 2003 Resource Kit Tools comes with utilities that can be used in tandem for this, called instsrv.exe and srvany.exe. See this Microsoft KB article KB137890 for details on how to use these utils.

    For Windows Home Server, there is a great user friendly wrapper for these utilities named aptly "Any Service Installer".

    Method 2: Use ServiceInstaller for Windows NT

    There is another alternative using ServiceInstaller for Windows NT (download-able here) with python instructions available. Contrary to the name, it works with both Windows 2000 and Windows XP as well. Here are some instructions for how to install a python script as a service.

    Installing a Python script

    Run ServiceInstaller to create a new service. (In this example, it is assumed that python is installed at c:\python25)

    Service Name  : PythonTest
    Display Name : PythonTest 
    Startup : Manual (or whatever you like)
    Dependencies : (Leave blank or fill to fit your needs)
    Executable : c:\python25\python.exe
    Arguments : c:\path_to_your_python_script\test.py
    Working Directory : c:\path_to_your_python_script
    

    After installing, open the Control Panel's Services applet, select and start the PythonTest service.

    After my initial answer, I noticed there were closely related Q&A already posted on SO. See also:

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

    How do I make Windows aware of a service I have written in Python?

    0 讨论(0)
  • 2020-11-22 02:34

    Yes you can. I do it using the pythoncom libraries that come included with ActivePython or can be installed with pywin32 (Python for Windows extensions).

    This is a basic skeleton for a simple service:

    import win32serviceutil
    import win32service
    import win32event
    import servicemanager
    import socket
    
    
    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 interrupted by checking a flag, which you set in the SvcStop method

    0 讨论(0)
  • 2020-11-22 02:35

    Although I upvoted the chosen answer a couple of weeks back, in the meantime I struggled a lot more with this topic. It feels like having a special Python installation and using special modules to run a script as a service is simply the wrong way. What about portability and such?

    I stumbled across the wonderful Non-sucking Service Manager, which made it really simple and sane to deal with Windows Services. I figured since I could pass options to an installed service, I could just as well select my Python executable and pass my script as an option.

    I have not yet tried this solution, but I will do so right now and update this post along the process. I am also interested in using virtualenvs on Windows, so I might come up with a tutorial sooner or later and link to it here.

    0 讨论(0)
  • 2020-11-22 02:38

    pysc: Service Control Manager on Python

    Example script to run as a service taken from pythonhosted.org:

    from xmlrpc.server import SimpleXMLRPCServer
    
    from pysc import event_stop
    
    
    class TestServer:
    
        def echo(self, msg):
            return msg
    
    
    if __name__ == '__main__':
        server = SimpleXMLRPCServer(('127.0.0.1', 9001))
    
        @event_stop
        def stop():
            server.server_close()
    
        server.register_instance(TestServer())
        server.serve_forever()
    

    Create and start service

    import os
    import sys
    from xmlrpc.client import ServerProxy
    
    import pysc
    
    
    if __name__ == '__main__':
        service_name = 'test_xmlrpc_server'
        script_path = os.path.join(
            os.path.dirname(__file__), 'xmlrpc_server.py'
        )
        pysc.create(
            service_name=service_name,
            cmd=[sys.executable, script_path]
        )
        pysc.start(service_name)
    
        client = ServerProxy('http://127.0.0.1:9001')
        print(client.echo('test scm'))
    

    Stop and delete service

    import pysc
    
    service_name = 'test_xmlrpc_server'
    
    pysc.stop(service_name)
    pysc.delete(service_name)
    
    pip install pysc
    
    0 讨论(0)
提交回复
热议问题