英文:
Starting python infinite loop as windows service?
问题
我正在尝试学习一些新东西,也许这是一个基本的问题,但在谷歌上找不到解决方案。
我有一个Python脚本,需要作为Windows服务无限后台运行,以便更容易管理(停止、启动、删除和安装服务)。因为我计划从React应用程序中控制这个服务。
这是我的Python模拟代码:
import threading, time
def start():
while True:
time.sleep(1)
open(r'E:\test.log', 'w').write('hello\n')
threading.Thread(target=start).start()
由于我有一个无限循环,当服务启动时,它会超时,因为Python脚本没有返回退出状态。
这是我的PowerShell脚本来管理服务。
param(
[string]$arg1
)
# 定义服务名称、显示名称和描述
$serviceName = "nmsCore"
$displayName = "NMS CORE SERVICE"
$description = "这是一个示例服务。"
# 定义Python可执行文件和脚本的路径
$pythonExecutable = "E:\Python_Venv\env310_1\Scripts\python.exe"
$scriptPath = "E:\Working\nmscore\v1\pycode\nmscore_service.py"
$arg1_value = $arg1
# 使用switch语句处理不同的命令
switch ($arg1_value) {
"install" {
# 创建服务
New-Service -Name $serviceName -BinaryPathName "$pythonExecutable $scriptPath" -DisplayName $displayName -Description $description
Write-Output "Service installed."
}
"start" {
# 启动服务
Start-Service -Name $serviceName
Write-Output "Service started."
}
"stop" {
# 停止服务
Stop-Service -Name $serviceName
Write-Output "Service stopped."
}
"delete" {
# 删除服务
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."
}
}
如何将Python代码作为后台服务启动?如果有更好的方法,请提供建议。
英文:
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.
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
答案1
得分: 1
你必须将你的Python代码与运行它的操作系统分开,作为后台服务运行。正如你注意到的,每个操作系统都以自己的方式运行,所以例如Windows与Linux及其systemd
在运行应用程序时有不同的期望。
正确的方法是将你的代码库分成两部分:第一部分将满足操作系统的要求并处理它期望遵循的协议(这就是你遇到的超时问题的原因:协议被违反,超时是操作系统的响应方式)。另一部分是执行工作的部分 - 启动后台的Thread
并执行你想要你的脚本完成的任务(请注意,它将以不同的用户和不同的权限和访问权限下启动,所以当涉及到某些文件时,你必须考虑到这一点)。
P.S. 处理Windows和它提供的“服务”子系统并不是一件容易的事情。如果你真的需要实施和支持它,请三思。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论