Python 3 Windows services are only started in Debug mode

Python 3 Windows services are only started in Debug mode … here is a solution to the problem.

Python 3 Windows services are only started in Debug mode

I first posted an answer in this post but it didn’t meet the forum standards. I hope that this time the answer meets the standards of the forum. This code should be clearer and easier to read.

In Python 3+, I use the following class to build a Windows service (it does nothing but write to a log file):

#MyWindowsService.py
import win32serviceutil
import servicemanager
import win32service
import win32event
import sys
import logging
import win32api

class MyWindowsService(win32serviceutil. ServiceFramework):
    _svc_name_          = 'ServiceName'
    _svc_display_name_  = 'Service Display Name'
    _svc_description_   = 'Service Full Description'
    logging.basicConfig(
        filename    = 'c:\\Temp\\{}.log'.format(_svc_name_),
        level       = logging. DEBUG,
        format      = '%(levelname)-7.7s @ %(asctime)s: %(message)s'
    )

def __init__(self, *args):
        self.log('Initializing service {}'.format(self._svc_name_))
        win32serviceutil. ServiceFramework.__init__(self, *args)
        self.stop_event = win32event. CreateEvent(None, 0, 0, None)

def SvcDoRun(self):
        self. ReportServiceStatus(win32service. SERVICE_START_PENDING)
        try:
            self.log('START: Service start')
            self. ReportServiceStatus(win32service. SERVICE_RUNNING)
            self.start()
            win32event. WaitForSingleObject(self.stop_event, win32event. INFINITE)
        except Exception as e:
            self.log('Exception: {}'.format(e))
            self. SvcStop()

def SvcStop(self):
        self.log('STOP: Service stopping...')
        self. ReportServiceStatus(win32service. SERVICE_STOP_PENDING)
        self.stop()
        win32event. SetEvent(self.stop_event)
        self. ReportServiceStatus(win32service. SERVICE_STOPPED)

def log(self, msg):
        servicemanager. LogInfoMsg(str(msg))  #system log
        logging.info(str(msg))               #text log

def start(self):
        self.runflag = True
        while self.runflag:
            win32api. Sleep((2*1000), True)
            self.log('Service alive')
    def stop(self): 
        self.runflag = False
        self.log('Stop received')

if __name__ == '__main__':
    win32serviceutil. HandleCommandLine(MyWindowsService)

In the script, I use the log file to check if it’s working. I’m running python 3.6 on Windows 7 (also tried python 3.4) and I’m having the following issues. When I run python MyWindowsService.py install, the prompt says the service is already installed (but nothing in the log file). If I try to start the service, I get Service Error: 1 – More info NET HELPMSG 3547 and does not account for the error. If I run python MyWindowsService.py debug, the program runs fine (log files are written), but I still can’t control the service: if I open another prompt and try to stop/start the service I still get the same result as above.

I

also tried inserting some debug code inside the init function, and when I run python MyWindowsService.py install, it doesn’t seem to be called. Is it possible?

I looked up multiple solutions and workarounds online but didn’t find the right one. What am I missing?

Solution

As eriksun pointed out in his comment on the first article, the problem is in the location of the python script, i.e. in a drive with a UNC path mapped – I’m using a virtual machine. Moving the python script to the same drive as the python installation did the job.
To summarize for future use, these are useful actions to try to fix the problem if the service fails to start and you are pretty sure about your code:

  • Use sc start ServiceName, sc query ServiceName, and sc stop ServiceName to get information about the service.
  • Check whether your files are in a physical drive or a UNC mapped drive. If the latter attempts to run a script using a UNC path (for example, python\\Server\share\python\your-folder\script.py) or move the script to the same drive as python for installation
  • Ensure that “python36.dll”, “vcruntime140.dll” and “pywintypes36.dll” are symbolically linked to directories with PythonService.exe; or symbolic link to the System32 directory; Or the directory with these DLLs is in the system (not user) path
  • Use the command reg query HKLM\System\CurrentControlSet\Services\your_service_name/s to check the system registers for more information about the script

Please feel free to finish, change, modify the last one so that it works for anyone like me who is experiencing this issue.

EDIT: One more thing… My project was supposed to actually work with network folders (and UNC-mapped drives), but it failed when I tried to get it to run as a service. A very useful (day-saving) resource I used to make it work was SysinternalsSuite by Mark Russinovich I found in this post. Hope this helps.

Related Problems and Solutions