(window.webpackJsonp=window.webpackJsonp||[]).push([[2681],{3089:function(t,s,a){"use strict";a.r(s);var n=a(31),e=Object(n.a)({},(function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"creating-a-windows-service-using-python"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#creating-a-windows-service-using-python"}},[t._v("#")]),t._v(" Creating a Windows service using Python")]),t._v(" "),a("p",[t._v("Headless processes (with no UI) in Windows are called Services. They can be controlled (started, stopped, etc) using standard Windows controls such as the command console, Powershell or the Services tab in Task Manager. A good example might be an application that provides network services, such as a web application, or maybe a backup application that performs various background archival tasks. There are several ways to create and install a Python application as a Service in Windows.")]),t._v(" "),a("h2",{attrs:{id:"a-python-script-that-can-be-run-as-a-service"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#a-python-script-that-can-be-run-as-a-service"}},[t._v("#")]),t._v(" A Python script that can be run as a service")]),t._v(" "),a("p",[t._v("The modules used in this example are part of "),a("a",{attrs:{href:"https://sourceforge.net/projects/pywin32/",target:"_blank",rel:"noopener noreferrer"}},[t._v("pywin32"),a("OutboundLink")],1),t._v(" (Python for Windows extensions). Depending on how you installed Python, you might need to install this separately.")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" win32serviceutil\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" win32service\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" win32event\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" servicemanager\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" socket\n\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AppServerSvc")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("win32serviceutil"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ServiceFramework"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n _svc_name_ "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"TestService"')]),t._v("\n _svc_display_name_ "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Test Service"')]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__init__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n win32serviceutil"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ServiceFramework"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("__init__"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("hWaitStop "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" win32event"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("CreateEvent"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("None")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("None")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n socket"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("setdefaulttimeout"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("60")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("SvcStop")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ReportServiceStatus"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("win32service"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("SERVICE_STOP_PENDING"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n win32event"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("SetEvent"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("hWaitStop"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("SvcDoRun")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n servicemanager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LogMsg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("servicemanager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("EVENTLOG_INFORMATION_TYPE"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n servicemanager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("PYS_SERVICE_STARTED"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_svc_name_"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("main"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("pass")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" __name__ "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'__main__'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n win32serviceutil"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("HandleCommandLine"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("AppServerSvc"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),a("p",[t._v("This is just boilerplate. Your application code, probably invoking a separate script, would go in the main() function.")]),t._v(" "),a("p",[t._v("You will also need to install this as a service. The best solution for this at the moment appears to be to use "),a("a",{attrs:{href:"http://nssm.cc/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Non-sucking Service Manager"),a("OutboundLink")],1),t._v(". This allows you to install a service and provides a GUI for configuring the command line the service executes. For Python you can do this, which creates the service in one go:")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[t._v("nssm install MyServiceName c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\\python27\\python"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exe c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\\temp\\myscript"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("py\n\n")])])]),a("p",[t._v("Where my_script.py is the boilerplate script above, modified to invoke your application script or code in the main() function. Note that the service doesn't run the Python script directly, it runs the Python interpreter and passes it the main script on the command line.")]),t._v(" "),a("p",[t._v("Alternatively you can use tools provided in the Windows Server Resource Kit for your operating system version so create the service.")]),t._v(" "),a("h2",{attrs:{id:"running-a-flask-web-application-as-a-service"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#running-a-flask-web-application-as-a-service"}},[t._v("#")]),t._v(" Running a Flask web application as a service")]),t._v(" "),a("p",[t._v("This is a variation on the generic example. You just need to import your app script and invoke it's "),a("code",[t._v("run()")]),t._v(" method in the service's "),a("code",[t._v("main()")]),t._v(" function. In this case we're also using the multiprocessing module due to an issue accessing "),a("code",[t._v("WSGIRequestHandler")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" win32serviceutil\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" win32service\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" win32event\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" servicemanager\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" multiprocessing "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Process\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" app "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" app\n\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Service")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("win32serviceutil"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ServiceFramework"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n _svc_name_ "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"TestService"')]),t._v("\n _svc_display_name_ "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Test Service"')]),t._v("\n _svc_description_ "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Tests Python service framework by receiving and echoing messages over a named pipe"')]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__init__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("__init__"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("SvcStop")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ReportServiceStatus"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("win32service"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("SERVICE_STOP_PENDING"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("process"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("terminate"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ReportServiceStatus"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("win32service"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("SERVICE_STOPPED"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("SvcDoRun")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("process "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Process"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("main"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("process"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("start"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("process"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("run"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n app"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("run"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" __name__ "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'__main__'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n win32serviceutil"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("HandleCommandLine"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Service"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),a("p",[t._v("Adapted from "),a("a",{attrs:{href:"http://stackoverflow.com/a/25130524/318488",target:"_blank",rel:"noopener noreferrer"}},[t._v("http://stackoverflow.com/a/25130524/318488"),a("OutboundLink")],1)])])}),[],!1,null,null,null);s.default=e.exports}}]);