Search code examples
python-3.xwindowsmultithreadingpowershellwindows-services

Starting python infinite loop as windows service?


I am trying to learn something new, maybe it is basic question but couldn't find solution on google.

I have python script which needs to be run in background infinitely as windows service for easier management ( STOP , START , DELETE and install the service ). Since I am planning to control this service from react application.

enter image description here

Here is my python code for simulation :

import threading ,time,sys
def start() :
    while True :
        time.sleep(1)
        open(r'E:\test.log', 'w').write('heelo\n')
threading.Thread(target=start).start()

Since I have infinite loop, when service is starting , it timeout because the py script is not returning an exit status.

here is my powershell script to manage the service.

param(
    [string]$arg1
)


# Define your service name, display name, and description
$serviceName = "nmsCore"
$displayName = "NMS CORE SERVICE"
$description = "This is a sample service."

# Define the path to your Python executable and the script
$pythonExecutable = "E:\Python_Venv\env310_1\Scripts\python.exe"
$scriptPath = "E:\Working\nmscore\v1\pycode\nmscore_service.py"
$arg1_value = $arg1
# Switch statement to handle different commands

switch ($arg1_value) {
    "install" {
        # Create the service
        New-Service -Name $serviceName -BinaryPathName "$pythonExecutable $scriptPath" -DisplayName $displayName -Description $description
        Write-Output "Service installed."
    }
    "start" {
        # Start the service
        Start-Service -Name $serviceName
        Write-Output "Service started."
    }
    "stop" {
        # Stop the service
        Stop-Service -Name $serviceName
        Write-Output "Service stopped."
    }
    "delete" {
        # Delete the service
        sc.exe delete $serviceName
        Write-Output "Service deleted."
    }

    "restart" {
        Stop-Service -Name $serviceName
        Start-Service -Name $serviceName
        Write-Output "Service updated."
    }

    "reinstall" {
        sc.exe delete $serviceName
        New-Service -Name $serviceName -BinaryPathName "$pythonExecutable $scriptPath" -DisplayName $displayName -Description $description
        Write-Output "Service re-installed."
    }


    default {
        Write-Output "Invalid command."
    }
}

How Would i start python code in background as service ? If also there is a better approach, Thanks to advise


Solution

  • You have to keep your Python separated from the OS that runs it as a background service. As you noticed, every OS does it in it's own way, so for example Windows posses a different set of expectations from the app it runs comparing to Linux and its systemd.

    The right way to get it done is to have your codebase split into two parts: the first one would fulfill the OS's requirements and handle the protocol it expects to be followed (there is where the timeout you're facing is coming from: protocol is violated and timeout is how OS responds back). The other second part is the one that does the job - the one which starts a background Thread and does whatever you want your script to do (be aware that it will be started under a different user with different set of rights and accesses, you have to take it into consideration when touching some files, for example).

    P.S. It is not really easy to deal with Windows and Services subsystem it provides. Think twice if you really need to implement and support it.