302

我正在勾画一组程序的架构,这些程序共享存储在数据库中的各种相互关联的对象。我希望其中一个程序充当服务,为对这些对象的操作提供更高级别的接口,而其他程序则通过该服务访问对象。

我目前的目标是将 Python 和 Django 框架作为实现该服务的技术。我很确定我知道如何在 Linux 中守护 Python 程序。但是,系统应该支持 Windows 是一个可选的规格项目。我几乎没有 Windows 编程经验,也完全没有 Windows 服务经验。

是否可以将 Python 程序作为 Windows 服务运行(即无需用户登录即可自动运行)?我不一定要实现这部分,但我需要一个粗略的想法,以便决定是否按照这些思路进行设计。

编辑:感谢到目前为止的所有答案,它们非常全面。我还想知道一件事:Windows 如何知道我的服务?我可以使用本机 Windows 实用程序对其进行管理吗? 什么相当于在 /etc/init.d 中放置启动/停止脚本?

4

13 回答 13

276

是的你可以。我使用ActivePython附带的 pythoncom 库来完成它,或者可以使用pywin32(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方法中设置的标志来中断

于 2008-08-28T14:39:04.763 回答
70

最简单的方法是使用:NSSM - Non-Sucking Service Manager。只需下载并解压缩到您选择的位置。它是一个独立的实用程序,大约 300KB(远小于为此目的而安装整个 pywin32 套件)并且不需要“安装”。zip 包含该实用程序的 64 位和 32 位版本。两者都应该在当前系统上运行良好(您可以使用 32 位版本来管理 64 位系统上的服务)。

图形用户界面方法

1 - 将 python 程序安装为服务。以管理员身份打开 Win 提示符

c:\>nssm.exe install WinService

2 - 在 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
于 2017-09-27T14:05:43.313 回答
52

尽管几周前我对所选择的答案投了赞成票,但与此同时,我在这个话题上挣扎了很多。感觉就像有一个特殊的 Python 安装和使用特殊的模块来运行一个脚本作为服务是完全错误的方式。便携性之类的呢?

我偶然发现了出色的Non-sucking Service Manager,它使处理 Windows 服务变得非常简单和理智。我想既然我可以将选项传递给已安装的服务,我也可以选择我的 Python 可执行文件并将我的脚本作为选项传递。

我还没有尝试过这个解决方案,但我现在会这样做,并在这个过程中更新这篇文章。我也对在 Windows 上使用 virtualenvs 感兴趣,所以我迟早会想出一个教程并在此处链接到它。

于 2014-07-28T13:41:31.923 回答
31

实现这一点的最简单方法是使用本机命令 sc.exe:

sc create PythonApp binPath= "C:\Python34\Python.exe --C:\tmp\pythonscript.py"

参考:

  1. https://technet.microsoft.com/en-us/library/cc990289(v=ws.11).aspx
  2. 使用 sc.exe 创建服务时如何传入上下文参数?
于 2016-12-07T12:23:51.380 回答
23

几乎所有 Windows 可执行文件都可以通过多种方式安装为服务。

方法一:使用 rktools.exe 中的 instsrv 和 srvany

对于 Windows Home Server 或 Windows Server 2003(也可与 WinXP 一起使用),Windows Server 2003 资源工具包工具附带了可以为此串联使用的实用程序,称为instsrv.exesrvany.exe。有关如何使用这些实用程序的详细信息, 请参阅此 Microsoft 知识库文章KB137890 。

对于 Windows Home Server,这些实用程序有一个很好的用户友好包装器,其名称恰如其分地命名为“ Any Service Installer ”。

方法 2: 使用 Windows NT 的 ServiceInstaller

还有另一种方法是使用Windows NT 的 ServiceInstaller可在此处下载),并提供python 指令。与名称相反,它也适用于 Windows 2000 和 Windows XP。以下是有关如何将 python 脚本安装为服务的一些说明。

安装 Python 脚本

运行 ServiceInstaller 以创建新服务。(本例假设python安装在c:\python25)

Service Name  : PythonTest
Display Name : PythonTest 
Startup : Manual (or whatever you like)
Dependencies : (Leave blank or fill to fit your needs)
Executable : c:\python25\python.exe
Arguments : c:\path_to_your_python_script\test.py
Working Directory : c:\path_to_your_python_script

安装后,打开控制面板的服务小程序,选择并启动PythonTest服务。

在我最初的回答之后,我注意到 SO 上已经发布了密切相关的问答。也可以看看:

我可以将 Python 脚本作为服务运行(在 Windows 中)吗?如何?

如何让 Windows 知道我用 Python 编写的服务?

于 2009-02-28T08:30:54.350 回答
20

逐步解释如何使其工作:

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 文件。

于 2017-06-29T08:37:26.677 回答
6

pysc:Python 上的服务控制管理器

作为从 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
于 2017-03-03T20:29:41.523 回答
5

python中的nssm 3+

(我使用pyinstaller将我的 .py 文件转换为 .exe )

nssm:如前所述

  • 运行 nssm install {ServiceName}
  • 在 NSSM 的控制台上:

    路径:path\to\your\program.exe

    启动目录:path\to\your\ #与路径相同但没有你的program.exe

    参数:空

如果您不想将项目转换为 .exe

  • 创建一个 .bat 文件python {{your python.py file name}}
  • 并设置 .bat 文件的路径
于 2019-06-04T21:42:05.600 回答
4

我开始使用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,因为它是在这个答案中提出的。迁移到它非常容易。

于 2018-10-12T13:07:47.503 回答
2

使用循环或子线程的完整 pywin32 示例

在断断续续地工作了几天之后,这是我希望找到的答案,使用 pywin32 来保持它的美观和独立。

这是一个基于循环和一个基于线程的解决方案的完整工作代码。它可能适用于 python 2 和 3,尽管我只在 2.7 和 Win7 上测试了最新版本。循环应该适用于轮询代码,而线程应该适用于更多类似服务器的代码。它似乎与没有标准方式正常关闭的女服务员wsgi 服务器很好地配合使用。

我还想指出,那里似乎有很多示例,像这样几乎有用,但实际上具有误导性,因为他们盲目地剪切和粘贴了其他示例。我可能是错的。但是,如果您从不等待它,为什么还要创建一个事件呢?

也就是说,我仍然觉得我在这里有点不稳定,特别是关于线程版本的退出有多干净,但至少我相信这里没有任何误导

要运行,只需将代码复制到文件并按照说明进行操作。

更新:

使用一个简单的标志来终止线程。重要的是“线程完成”打印。
有关从不合作的服务器线程退出的更详细的示例,请参阅我关于女服务员 wsgi 服务器的帖子

# 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()
于 2020-01-26T21:52:44.667 回答
1

这个答案是来自 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
于 2020-11-01T22:22:07.013 回答
0

接受的答案使用win32serviceutil工作但很复杂,并且使调试和更改更加困难。使用 NSSM(非吸吮服务管理器)要容易得多。您编写并舒适地调试一个普通的 python 程序,当它最终工作时,您使用 NSSM 在不到一分钟的时间内将其安装为服务:

从提升的(管理员)命令提示符运行nssm.exe install NameOfYourService并填写以下选项:

  • 路径:(python.exe 的路径,例如C:\Python27\Python.exe
  • 参数:(您的 python 脚本的路径,例如c:\path\to\program.py

顺便说一句,如果您的程序打印出有用的消息,并且您希望将这些消息保存在日志文件中,那么 NSSM 也可以为您处理这个以及更多的事情。

于 2018-11-10T15:52:08.010 回答
-1

https://www.chrisumbel.com/article/windows_services_in_python

  1. 跟进 PySvc.py

  2. 更改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
  1. 更改python文件夹的路径

cd C:\Users\user\AppData\Local\Programs\Python\Python38-32

  1. NET START PySvc
  2. NET STOP PySvc
于 2020-03-20T14:15:04.310 回答