我正在勾画一组程序的架构,这些程序共享存储在数据库中的各种相互关联的对象。我希望其中一个程序充当服务,为对这些对象的操作提供更高级别的接口,而其他程序则通过该服务访问对象。
我目前的目标是将 Python 和 Django 框架作为实现该服务的技术。我很确定我知道如何在 Linux 中守护 Python 程序。但是,系统应该支持 Windows 是一个可选的规格项目。我几乎没有 Windows 编程经验,也完全没有 Windows 服务经验。
是否可以将 Python 程序作为 Windows 服务运行(即无需用户登录即可自动运行)?我不一定要实现这部分,但我需要一个粗略的想法,以便决定是否按照这些思路进行设计。
编辑:感谢到目前为止的所有答案,它们非常全面。我还想知道一件事:Windows 如何知道我的服务?我可以使用本机 Windows 实用程序对其进行管理吗?什么相当于在 /etc/init.d 中放置启动/停止脚本?
是的你可以。我使用 ActivePython 附带的或可以与 pywin32 一起安装的 pythoncom 库(Windows 扩展的 Python)来执行此操作。
这是一个简单服务的基本框架:
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
class AppServerSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test 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):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,''))
self.main()
def main(self):
pass
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(AppServerSvc)
您的代码将进入 main()
方法 - 通常带有某种无限循环,可能会通过检查您在 SvcStop
方法中设置的标志来中断
最简单的方法是使用: NSSM - Non-Sucking Service Manager。只需下载并解压缩到您选择的位置。它是一个独立的实用程序,大约 300KB(远小于为此目的而安装整个 pywin32 套件)并且不需要“安装”。 zip 包含该实用程序的 64 位和 32 位版本。两者都应该在当前系统上运行良好(您可以使用 32 位版本来管理 64 位系统上的服务)。
图形用户界面方法
- 将 python 程序安装为服务。以管理员身份打开 Win 提示符
c:\>nssm.exe install WinService
- 在 NSSM 的 GUI 控制台上:
路径:C:\Python27\Python27.exe
启动目录:C:\Python27
参数:c:\WinService.py
3 - 检查 services.msc 上创建的服务
脚本方法(无 GUI)
如果您的服务应该是自动化、非交互式过程的一部分,这可能会超出您的控制范围,例如批处理或安装程序脚本,这将非常方便。假设命令以管理权限执行。
为方便起见,此处通过简单地将实用程序称为 nssm.exe
来描述这些命令。但是,建议使用完整路径 c:\path\to\nssm.exe
在脚本中更明确地引用它,因为它是一个独立的可执行文件,可能位于系统不知道的私有路径中。
1.安装服务
您必须指定服务的名称、正确 Python 可执行文件的路径以及脚本的路径:
nssm.exe install ProjectService "c:\path\to\python.exe" "c:\path\to\project\app\main.py"
更明确地说:
nssm.exe install ProjectService
nssm.exe set ProjectService Application "c:\path\to\python.exe"
nssm.exe set ProjectService AppParameters "c:\path\to\project\app\main.py"
或者,您可能希望您的 Python 应用程序作为 Python 模块启动。一种简单的方法是告诉 nssm 它需要更改为正确的起始目录,就像您在从命令 shell 启动时所做的那样:
nssm.exe install ProjectService "c:\path\to\python.exe" "-m app.main"
nssm.exe set ProjectService AppDirectory "c:\path\to\project"
这种方法适用于虚拟环境和自包含(嵌入式)Python 安装。只需确保使用常用方法正确解决了这些环境中的任何路径问题。如果需要,nssm 可以设置环境变量(例如 PYTHONPATH),还可以启动批处理脚本。
2.启动服务
nssm.exe start ProjectService
3.停止服务
nssm.exe stop ProjectService
<强> 4。要删除服务,请指定 confirm
参数以跳过交互式确认。
nssm.exe remove ProjectService confirm
尽管几周前我对所选择的答案投了赞成票,但与此同时,我在这个话题上挣扎了很多。感觉就像有一个特殊的 Python 安装和使用特殊的模块来运行一个脚本作为服务是完全错误的方式。便携性之类的呢?
我偶然发现了精彩的 Non-sucking Service Manager,它使处理 Windows 服务变得非常简单和理智。我想既然我可以将选项传递给已安装的服务,我也可以选择我的 Python 可执行文件并将我的脚本作为选项传递。
我还没有尝试过这个解决方案,但我现在会这样做,并在这个过程中更新这篇文章。我也对在 Windows 上使用 virtualenvs 感兴趣,所以我迟早会想出一个教程并在此处链接到它。
new-service
应该能够做到这一点,但是将脚本作为服务启动(和监视)显然涉及更多的细节,nssm 很好地处理了这些细节。
实现这一点的最简单方法是使用本机命令 sc.exe:
sc create PythonApp binPath= "C:\Python34\Python.exe --C:\tmp\pythonscript.py"
参考:
https://technet.microsoft.com/en-us/library/cc990289(v=ws.11).aspx 使用 sc.exe 创建服务时如何传入上下文参数?
几乎所有 Windows 可执行文件都可以通过多种方式安装为服务。
方法一:使用 rktools.exe 中的 instsrv 和 srvany
对于 Windows Home Server 或 Windows Server 2003(也可与 WinXP 一起使用),Windows Server 2003 Resource Kit Tools 附带了可以为此串联使用的实用程序,称为 instsrv.exe 和 srvany.exe< /强>。有关如何使用这些实用程序的详细信息,请参阅此 Microsoft 知识库文章 KB137890。
对于 Windows Home Server,有一个对这些实用程序非常友好的包装器,名称恰当地命名为“Any Service Installer”。
方法 2: 使用 Windows NT 的 ServiceInstaller
还有另一种将 ServiceInstaller for Windows NT (download-able here) 与 python instructions available 结合使用的替代方法。与名称相反,它也适用于 Windows 2000 和 Windows XP。以下是有关如何将 python 脚本安装为服务的一些说明。
安装 Python 脚本 运行 ServiceInstaller 以创建新服务。 (在此示例中,假设 python 安装在 c:\python25 )服务名称:PythonTest 显示名称:PythonTest 启动:手动(或任何您喜欢的)依赖项:(留空或填写以适应您的需要)可执行文件:c :\python25\python.exe 参数:c:\path_to_your_python_script\test.py 工作目录:c:\path_to_your_python_script 安装后,打开控制面板的服务小程序,选择并启动PythonTest服务。
在我最初的回答之后,我注意到 SO 上已经发布了密切相关的问答。也可以看看:
Can I run a Python script as a service (in Windows)? How?
How do I make Windows aware of a service I have written in Python?
NT
不一定与名称“相反”,至少在程序员的民间演讲中不会。它只是指“NT architecture”,而不是“NT brand”。这就是说,根据 talk on wikipedia,这是有争议的,因为“这不是 Microsoft 的官方术语”,但这种思路仍然存在传统。
逐步解释如何使其工作:
1-首先根据上面提到的基本骨架创建一个python文件。并将其保存到例如路径:“c:\PythonFiles\AppServerSvc.py”
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
class AppServerSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test 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):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,''))
self.main()
def main(self):
# Your business logic or call to any class should be here
# this time it creates a text.txt and writes Test Service in a daily manner
f = open('C:\\test.txt', 'a')
rc = None
while rc != win32event.WAIT_OBJECT_0:
f.write('Test Service \n')
f.flush()
# block for 24*60*60 seconds and wait for a stop event
# it is used for a one-day loop
rc = win32event.WaitForSingleObject(self.hWaitStop, 24 * 60 * 60 * 1000)
f.write('shut down \n')
f.close()
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(AppServerSvc)
2 - 在这一步我们应该注册我们的服务。
以管理员身份运行命令提示符并键入:
sc create TestService binpath= "C:\Python36\Python.exe c:\PythonFiles\AppServerSvc.py" DisplayName= "TestService" start= auto
binpath的第一个参数是python.exe的路径
binpath 的第二个参数是我们已经创建的 python 文件的路径
不要错过你应该在每个“=”符号后放置一个空格。
然后如果一切正常,你应该看到
[SC] 创建服务成功
现在您的 python 服务已安装为 Windows 服务。您可以在以下服务管理器和注册表中看到它:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TestService
3- 现在好了。您可以在服务管理器上启动您的服务。
您可以执行每个提供此服务框架的 python 文件。
SetEvent(self.hWaitStop)
和 WaitForSingleObject
有很多不好的例子。可能是基于此处所选答案的轻率复制。这是一个很好的方法,它对“调试”结束和“停止”参数都有效。 (当 HandleCommandLine
完成这项工作时,关于使用 SC 的部分似乎是多余的,并且可以运行调试。)
install
参数来工作。
pysc:Service Control Manager on Python
作为服务运行的示例脚本 taken from pythonhosted.org:
from xmlrpc.server import SimpleXMLRPCServer from pysc import event_stop class TestServer: def echo(self, msg): return msg if __name__ == '__main__': server = SimpleXMLRPCServer(('127.0.0.1', 9001)) @event_stop def stop( ): server.server_close() server.register_instance(TestServer()) server.serve_forever() 创建并启动服务 import os import sys from xmlrpc.client import ServerProxy import pysc if __name__ == '__main__': service_name = 'test_xmlrpc_server' script_path = os.path.join(os.path.dirname(__file__), 'xmlrpc_server.py') pysc.create( service_name=service_name, cmd=[sys.executable, script_path]) pysc.start(service_name) client = ServerProxy( 'http://127.0.0.1:9001') print(client.echo('test scm')) 停止并删除服务 import pysc service_name = 'test_xmlrpc_server' pysc.stop(service_name) pysc.delete(service_name)
pip install pysc
nssm 在 python 3+ 中
(我使用 pyinstaller 将我的 .py 文件转换为 .exe)
nssm:如前所述
运行 nssm install {ServiceName}
在 NSSM 的控制台上:路径:path\to\your\program.exe 启动目录:path\to\your\ #same as the path but without your program.exe 参数:空
如果您不想将项目转换为 .exe
使用 python {{您的 python.py 文件名}} 创建一个 .bat 文件
并设置 .bat 文件的路径
我开始使用 pywin32 作为服务托管。
一切都很好,但我遇到了系统启动时服务无法在 30 秒内启动(Windows 默认超时)的问题。这对我来说至关重要,因为 Windows 启动是在一台物理机上托管的多个虚拟机上同时进行的,并且 IO 负载非常大。错误消息是:
Error 1053: The service did not respond to the start or control request in a timely fashion.
Error 7009: Timeout (30000 milliseconds) waiting for the <ServiceName> service to connect.
我与 pywin 进行了很多斗争,但最终还是使用了建议的 NSSM in this answer。迁移到它非常容易。
使用循环或子线程的完整 pywin32 示例
在断断续续地工作了几天之后,这是我希望找到的答案,使用 pywin32 来保持它的美观和独立。
这是一个基于循环和一个基于线程的解决方案的完整工作代码。它可能适用于 python 2 和 3,尽管我只在 2.7 和 Win7 上测试了最新版本。循环应该适用于轮询代码,而线程应该适用于更多类似服务器的代码。它似乎与没有标准方式正常关闭的 waitress wsgi 服务器很好地配合使用。
我还想指出,那里似乎有很多示例,例如 this,它们几乎有用,但实际上具有误导性,因为它们盲目地剪切和粘贴了其他示例。我可能是错的。但是,如果您从不等待它,为什么还要创建一个事件呢?
也就是说,我仍然觉得我在这里有点不稳定,特别是关于线程版本的退出有多干净,但至少我相信这里没有任何误导。
要运行,只需将代码复制到文件并按照说明进行操作。
更新:
使用一个简单的标志来终止线程。重要的是打印“线程完成”。
有关从不合作的服务器线程退出的更详细的示例,请参阅我的 post about the waitress wsgi server。
# uncomment mainthread() or mainloop() call below
# run without parameters to see HandleCommandLine options
# install service with "install" and remove with "remove"
# run with "debug" to see print statements
# with "start" and "stop" watch for files to appear
# check Windows EventViever for log messages
import socket
import sys
import threading
import time
from random import randint
from os import path
import servicemanager
import win32event
import win32service
import win32serviceutil
# see http://timgolden.me.uk/pywin32-docs/contents.html for details
def dummytask_once(msg='once'):
fn = path.join(path.dirname(__file__),
'%s_%s.txt' % (msg, randint(1, 10000)))
with open(fn, 'w') as fh:
print(fn)
fh.write('')
def dummytask_loop():
global do_run
while do_run:
dummytask_once(msg='loop')
time.sleep(3)
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global do_run
do_run = True
print('thread start\n')
dummytask_loop()
print('thread done\n')
def exit(self):
global do_run
do_run = False
class SMWinservice(win32serviceutil.ServiceFramework):
_svc_name_ = 'PyWinSvc'
_svc_display_name_ = 'Python Windows Service'
_svc_description_ = 'An example of a windows service in Python'
@classmethod
def parse_command_line(cls):
win32serviceutil.HandleCommandLine(cls)
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.stopEvt = win32event.CreateEvent(None, 0, 0, None) # create generic event
socket.setdefaulttimeout(60)
def SvcStop(self):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, ''))
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.stopEvt) # raise event
def SvcDoRun(self):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
# UNCOMMENT ONE OF THESE
# self.mainthread()
# self.mainloop()
# Wait for stopEvt indefinitely after starting thread.
def mainthread(self):
print('main start')
self.server = MyThread()
self.server.start()
print('wait for win32event')
win32event.WaitForSingleObject(self.stopEvt, win32event.INFINITE)
self.server.exit()
print('wait for thread')
self.server.join()
print('main done')
# Wait for stopEvt event in loop.
def mainloop(self):
print('loop start')
rc = None
while rc != win32event.WAIT_OBJECT_0:
dummytask_once()
rc = win32event.WaitForSingleObject(self.stopEvt, 3000)
print('loop done')
if __name__ == '__main__':
SMWinservice.parse_command_line()
使用 win32serviceutil
的公认答案有效,但很复杂,使调试和更改更加困难。 远更容易使用 NSSM(the Non-Sucking Service Manager)。您编写并轻松调试一个普通的 Python 程序,当它最终工作时,您使用 NSSM 将其作为服务安装在少于一分钟:
从提升的(管理员)命令提示符运行 nssm.exe install NameOfYourService
并填写以下选项:
路径:(python.exe 的路径,例如 C:\Python27\Python.exe)
参数:(python 脚本的路径,例如 c:\path\to\program.py)
顺便说一句,如果您的程序打印出有用的消息,并且您希望将这些消息保存在日志文件中,NSSM 也可以为您处理这个以及更多的事情。
这个答案是来自 StackOverflow 上的几个来源的剽窃者——大部分都在上面,但我忘记了其他的——对不起。这很简单,脚本“按原样”运行。对于测试脚本的版本,然后将其复制到服务器并停止/启动相关服务。它应该适用于所有脚本语言(Python、Perl、node.js),以及 GitBash、PowerShell 等批处理脚本,甚至是旧的 DOS bat 脚本。 pyGlue 是位于 Windows 服务和脚本之间的粘合剂。
'''
A script to create a Windows Service, which, when started, will run an executable with the specified parameters.
Optionally, you can also specify a startup directory
To use this script you MUST define (in class Service)
1. A name for your service (short - preferably no spaces)
2. A display name for your service (the name visibile in Windows Services)
3. A description for your service (long details visible when you inspect the service in Windows Services)
4. The full path of the executable (usually C:/Python38/python.exe or C:WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe
5. The script which Python or PowerShell will run(or specify None if your executable is standalone - in which case you don't need pyGlue)
6. The startup directory (or specify None)
7. Any parameters for your script (or for your executable if you have no script)
NOTE: This does not make a portable script.
The associated '_svc_name.exe' in the dist folder will only work if the executable,
(and any optional startup directory) actually exist in those locations on the target system
Usage: 'pyGlue.exe [options] install|update|remove|start [...]|stop|restart [...]|debug [...]'
Options for 'install' and 'update' commands only:
--username domain\\username : The Username the service is to run under
--password password : The password for the username
--startup [manual|auto|disabled|delayed] : How the service starts, default = manual
--interactive : Allow the service to interact with the desktop.
--perfmonini file: .ini file to use for registering performance monitor data
--perfmondll file: .dll file to use when querying the service for performance data, default = perfmondata.dll
Options for 'start' and 'stop' commands only:
--wait seconds: Wait for the service to actually start or stop.
If you specify --wait with the 'stop' option, the service and all dependent services will be stopped,
each waiting the specified period.
'''
# Import all the modules that make life easy
import servicemanager
import socket
import sys
import win32event
import win32service
import win32serviceutil
import win32evtlogutil
import os
from logging import Formatter, Handler
import logging
import subprocess
# Define the win32api class
class Service (win32serviceutil.ServiceFramework):
# The following variable are edited by the build.sh script
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
_svc_description_ = "Test Running Python Scripts as a Service"
service_exe = 'c:/Python27/python.exe'
service_script = None
service_params = []
service_startDir = None
# Initialize the service
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
self.configure_logging()
socket.setdefaulttimeout(60)
# Configure logging to the WINDOWS Event logs
def configure_logging(self):
self.formatter = Formatter('%(message)s')
self.handler = logHandler()
self.handler.setFormatter(self.formatter)
self.logger = logging.getLogger()
self.logger.addHandler(self.handler)
self.logger.setLevel(logging.INFO)
# Stop the service
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
# Run the service
def SvcDoRun(self):
self.main()
# This is the service
def main(self):
# Log that we are starting
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
# Fire off the real process that does the real work
logging.info('%s - about to call Popen() to run %s %s %s', self._svc_name_, self.service_exe, self.service_script, self.service_params)
self.process = subprocess.Popen([self.service_exe, self.service_script] + self.service_params, shell=False, cwd=self.service_startDir)
logging.info('%s - started process %d', self._svc_name_, self.process.pid)
# Wait until WINDOWS kills us - retrigger the wait for stop every 60 seconds
rc = None
while rc != win32event.WAIT_OBJECT_0:
rc = win32event.WaitForSingleObject(self.hWaitStop, (1 * 60 * 1000))
# Shut down the real process and exit
logging.info('%s - is terminating process %d', self._svc_name_, self.process.pid)
self.process.terminate()
logging.info('%s - is exiting', self._svc_name_)
class logHandler(Handler):
'''
Emit a log record to the WINDOWS Event log
'''
def emit(self, record):
servicemanager.LogInfoMsg(record.getMessage())
# The main code
if __name__ == '__main__':
'''
Create a Windows Service, which, when started, will run an executable with the specified parameters.
'''
# Check that configuration contains valid values just in case this service has accidentally
# been moved to a server where things are in different places
if not os.path.isfile(Service.service_exe):
print('Executable file({!s}) does not exist'.format(Service.service_exe), file=sys.stderr)
sys.exit(0)
if not os.access(Service.service_exe, os.X_OK):
print('Executable file({!s}) is not executable'.format(Service.service_exe), file=sys.stderr)
sys.exit(0)
# Check that any optional startup directory exists
if (Service.service_startDir is not None) and (not os.path.isdir(Service.service_startDir)):
print('Start up directory({!s}) does not exist'.format(Service.service_startDir), file=sys.stderr)
sys.exit(0)
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(Service)
servicemanager.StartServiceCtrlDispatcher()
else:
# install/update/remove/start/stop/restart or debug the service
# One of those command line options must be specified
win32serviceutil.HandleCommandLine(Service)
现在有一些编辑,你不希望你的所有服务都称为“pyGlue”。所以有一个脚本 (build.sh) 可以插入这些位并创建一个自定义的“pyGlue”并创建一个“.exe”。正是这个“.exe”作为 Windows 服务安装。安装后,您可以将其设置为自动运行。
#!/bin/sh
# This script build a Windows Service that will install/start/stop/remove a service that runs a script
# That is, executes Python to run a Python script, or PowerShell to run a PowerShell script, etc
if [ $# -lt 6 ]; then
echo "Usage: build.sh Name Display Description Executable Script StartupDir [Params]..."
exit 0
fi
name=$1
display=$2
desc=$3
exe=$4
script=$5
startDir=$6
shift; shift; shift; shift; shift; shift
params=
while [ $# -gt 0 ]; do
if [ "${params}" != "" ]; then
params="${params}, "
fi
params="${params}'$1'"
shift
done
cat pyGlue.py | sed -e "s/pyGlue/${name}/g" | \
sed -e "/_svc_name_ =/s?=.*?= '${name}'?" | \
sed -e "/_svc_display_name_ =/s?=.*?= '${display}'?" | \
sed -e "/_svc_description_ =/s?=.*?= '${desc}'?" | \
sed -e "/service_exe =/s?=.*?= '$exe'?" | \
sed -e "/service_script =/s?=.*?= '$script'?" | \
sed -e "/service_params =/s?=.*?= [${params}]?" | \
sed -e "/service_startDir =/s?=.*?= '${startDir}'?" > ${name}.py
cxfreeze ${name}.py --include-modules=win32timezone
安装 - 将“.exe”服务器和脚本复制到指定文件夹。使用“安装”选项以管理员身份运行“.exe”。以管理员身份打开 Windows 服务,然后启动您的服务。对于升级,只需复制新版本的脚本并停止/启动服务。
现在每台服务器都是不同的——不同的 Python 安装,不同的文件夹结构。我为每个服务器维护一个文件夹,其中包含 pyGlue.py 和 build.sh 的副本。我创建了一个“serverBuild.sh”脚本来重建该服务器上的所有服务。
# A script to build all the script based Services on this PC
sh build.sh AutoCode 'AutoCode Medical Documents' 'Autocode Medical Documents to SNOMED_CT and AIHW codes' C:/Python38/python.exe autocode.py C:/Users/russell/Documents/autocoding -S -T
这不能回答最初的问题,但可能会帮助其他想要在 Windows 启动时自动启动 Python 脚本的人:看看 Windows Task Scheduler,如果您只想在启动后启动脚本,这会更容易没有 Windows 服务的所有服务功能。
创建一个新任务,选择“启动时”作为触发器,选择“启动程序”作为操作,将“C:\Python39\python.exe”作为程序(或任何你的 python.exe 所在的位置)和脚本的完整路径( “C:...\my_dir\xyz.py”)作为参数(如果路径包含空格,您可以使用“)。您还可以选择脚本的路径(没有 .py 文件,例如“C:.. .\my_dir") 如果您在脚本中使用相对路径,例如用于记录,则表示“开始”。
https://www.chrisumbel.com/article/windows_services_in_python
跟进 PySvc.py 更改 dll 文件夹
我知道这很旧,但我一直坚持这一点。对我来说,这个特定的问题是通过复制这个文件解决的 - pywintypes36.dll
从 -> Python36\Lib\site-packages\pywin32_system32
到 -> Python36\Lib\site-packages\win32
setx /M PATH "%PATH%;C:\Users\user\AppData\Local\Programs\Python\Python38-32;C:\Users\user\AppData\Local\Programs\Python\Python38-32\Scripts;C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\pywin32_system32;C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\win32
更改python文件夹的路径
cd C:\Users\user\AppData\Local\Programs\Python\Python38-32
网络启动 PySvc 网络停止 PySvc
python my_script_as_service.py install
?socket.setdefaulttimeout(60)
是?它是服务所需要的,还是只是从某些现有服务中意外复制的? :)