Uplink Code as a Windows Service

I wanted a way to run uplink code on my client’s system without them having to install/maintain/understand anything that didn’t look familiar. I decided to create an installable Windows Service based on a gist at https://gist.github.com/guillaumevincent/d8d94a0a44a7ec13def7f96bfb713d3f

import os
import socket
import sys

import anvil.server
import servicemanager
import win32event
import win32service
import win32serviceutil

ANVIL_KEY = os.environ['ANVIL_KEY']

@anvil.server.callable
def hello():
    return 'hello world' 

class UplinkService(win32serviceutil.ServiceFramework):
    _svc_name_ = "UplinkService"
    _svc_display_name_ = "Uplink 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):
        self.ReportServiceStatus(win32service.SERVICE_RUNNING)
        rc = None
        anvil.server.connect(ANVIL_KEY)
        while rc != win32event.WAIT_OBJECT_0:
            rc = win32event.WaitForSingleObject(self.hWaitStop, 5000)


if __name__ == '__main__':
    if len(sys.argv) == 1:
        servicemanager.Initialize()
        servicemanager.PrepareToHostSingle(UplinkService)
        servicemanager.StartServiceCtrlDispatcher()
    else:
        win32serviceutil.HandleCommandLine(UplinkService)
5 Likes

Further Update

I’ve refactored my Windows Service code to create a re-usable library and published it to github and pypi:

7 Likes

Great topic! Well done @owen.campbell !!

Sadly I did not search this forum before I started to search the web :frowning:

Anyhow, I hope someone find my example useful. It also includes a Windows Installer :slight_smile:
https://github.com/manprinsen/python-script-to-windows-installer-as-a-windows-service

I tried your instructions but failed. But then I found this instruction on Medium, and that one worked for me. I think actually it does the same, but easier, for me at least.