Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

People also ask

How do I run Python on Windows?

Go to your Start menu (lower left Windows icon), type "Microsoft Store", select the link to open the store. Once the store is open, select Search from the upper-right menu and enter "Python". Select which version of Python you would like to use from the results under Apps.


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


The simplest way is to use the: NSSM - the Non-Sucking Service Manager. Just download and unzip to a location of your choosing. It's a self-contained utility, around 300KB (much less than installing the entire pywin32 suite just for this purpose) and no "installation" is needed. The zip contains a 64-bit and a 32-bit version of the utility. Either should work well on current systems (you can use the 32-bit version to manage services on 64-bit systems).

GUI approach

1 - install the python program as a service. Open a Win prompt as admin

c:\>nssm.exe install WinService

2 - On NSSM´s GUI console:

path: C:\Python27\Python27.exe

Startup directory: C:\Python27

Arguments: c:\WinService.py

3 - check the created services on services.msc

Scripting approach (no GUI)

This is handy if your service should be part of an automated, non-interactive procedure, that may be beyond your control, such as a batch or installer script. It is assumed that the commands are executed with administrative privileges.

For convenience the commands are described here by simply referring to the utility as nssm.exe. It is advisable, however, to refer to it more explicitly in scripting with its full path c:\path\to\nssm.exe, since it's a self-contained executable that may be located in a private path that the system is not aware of.

1. Install the service

You must specify a name for the service, the path to the proper Python executable, and the path to the script:

nssm.exe install ProjectService "c:\path\to\python.exe" "c:\path\to\project\app\main.py"

More explicitly:

nssm.exe install ProjectService 
nssm.exe set ProjectService Application "c:\path\to\python.exe"
nssm.exe set ProjectService AppParameters "c:\path\to\project\app\main.py"

Alternatively you may want your Python app to be started as a Python module. One easy approach is to tell nssm that it needs to change to the proper starting directory, as you would do yourself when launching from a command shell:

nssm.exe install ProjectService "c:\path\to\python.exe" "-m app.main"
nssm.exe set ProjectService AppDirectory "c:\path\to\project"

This approach works well with virtual environments and self-contained (embedded) Python installs. Just make sure to have properly resolved any path issues in those environments with the usual methods. nssm has a way to set environment variables (e.g. PYTHONPATH) if needed, and can also launch batch scripts.

2. To start the service

nssm.exe start ProjectService 

3. To stop the service

nssm.exe stop ProjectService

4. To remove the service, specify the confirm parameter to skip the interactive confirmation.

nssm.exe remove ProjectService confirm

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.


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?

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?