什么是 Windows 服务?
Windows 服务(在早期版本中也称为 NT 服务)是一种在后台运行的应用程序,它没有用户界面,并且可以在用户登录之前启动,它们通常用于需要长期运行、自动启动或在特定系统事件(如系统启动时)执行任务的应用程序,

- 数据库服务器
- Web 服务器
- 定时任务调度器
- 文件监控服务
- 系统监控工具
核心概念
在创建 Python 服务之前,你需要了解几个核心概念:
- 服务名称: 一个唯一的名称,用于在系统中标识你的服务(
MyPythonService)。 - 显示名称: 用户在服务管理器中看到的友好名称("My Awesome Python Service")。
- 描述: 对服务功能的详细描述。
- 启动类型:
自动: Windows 启动时自动运行。手动: 需要手动启动或通过其他程序触发。禁用: 服务被禁用,无法启动。
- 服务账户: 服务以哪个用户的身份运行。
LocalSystem: 功能最强大的本地系统账户,有很高的权限。LocalService: 具有较低权限的本地账户,用于访问网络资源。NetworkService: 与LocalService类似,但更侧重于网络访问。- 特定用户账户:使用指定的用户名和密码运行。
- 事件日志: 服务通过 Windows 事件日志来记录运行状态、错误和信息,这对于调试至关重要。
实现方法
主要有两种流行的方式来创建 Python Windows 服务:
- 使用第三方库(推荐): 这是最简单、最快捷的方式,库已经为你处理了所有与 Windows API 交互的复杂工作。
- 使用原生 Python 模块 (
pywin32): 提供了更底层的控制,但代码更复杂。
使用 pywin32 库
这是最经典和最直接的方法,它直接调用 Windows API。
步骤 1: 安装 pywin32
pip install pywin32
步骤 2: 编写 Python 脚本
创建一个名为 my_service.py 的文件,这个脚本需要包含一个主类,继承自 win32serviceutil.ServiceFramework。

# my_service.py
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import time
import logging
# --- 配置你的服务 ---
SERVICE_NAME = "MyPythonService"
SERVICE_DISPLAY_NAME = "My Awesome Python Service"
SERVICE_DESCRIPTION = "This is a sample Python service that runs in the background."
class MyPythonService(win32serviceutil.ServiceFramework):
"""
Python 服务示例
"""
_svc_name_ = SERVICE_NAME
_svc_display_name_ = SERVICE_DISPLAY_NAME
_svc_description_ = SERVICE_DESCRIPTION
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
# 在这里初始化你的应用
self.logger = self._setup_logger()
self.logger.info(f"'{self._svc_display_name_}' 服务正在启动...")
def _setup_logger(self):
"""配置日志记录到 Windows 事件日志"""
logger = logging.getLogger(SERVICE_NAME)
logger.setLevel(logging.INFO)
# 创建一个 handler 来写入 Windows 事件日志
handler = servicemanager.EventLogHandler()
formatter = logging.Formatter(f'%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
def SvcStop(self):
"""停止服务"""
self.logger.info("服务停止请求已收到。")
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
"""服务的主运行循环"""
self.logger.info("服务主循环已启动。")
# 在这里放置你的主要服务逻辑
try:
while True:
# 模拟工作
self.logger.info("服务正在运行...")
time.sleep(5)
# 检查停止事件
if win32event.WaitForSingleObject(self.hWaitStop, 0) == win32event.WAIT_OBJECT_0:
break
except Exception as e:
self.logger.error(f"服务运行时发生错误: {e}", exc_info=True)
finally:
self.logger.info("服务已停止。")
if __name__ == '__main__':
# 如果直接运行此脚本,则安装服务
if len(sys.argv) == 1:
# 安装服务
win32serviceutil.HandleCommandLine(MyPythonService)
else:
# 如果由服务控制管理器启动,则运行服务
win32serviceutil.ServiceFramework.__init__(sys.modules[__name__], sys.argv)
步骤 3: 安装服务
以管理员身份打开命令提示符 (CMD) 或 PowerShell,然后运行你的脚本:
python my_service.py install
这会执行 win32serviceutil.HandleCommandLine 中的 install 命令,将你的服务注册到 Windows 服务管理器中。
步骤 4: 启动和管理服务
你可以使用标准的 Windows 命令或服务管理器来控制你的服务。
命令行方式 (管理员 CMD/PowerShell):

-
启动服务:
net start MyPythonService
或者使用
sc命令:sc start MyPythonService
-
停止服务:
net stop MyPythonService
或者:
sc stop MyPythonService
-
删除服务:
python my_service.py remove
或者使用
sc:sc delete MyPythonService
图形界面方式:
- 按
Win + R,输入services.msc并回车。 - 在服务列表中找到 "My Awesome Python Service"。
- 你可以右键点击它来启动、停止、暂停或重新启动。
- 双击它可以查看属性,修改启动类型(自动/手动/禁用)或查看事件日志。
使用 pywin32-service 库 (更现代的封装)
这个库是对 pywin32 的一个更高级的封装,语法更简洁,推荐用于新项目。
步骤 1: 安装 pywin32-service
pip install pywin32-service
步骤 2: 编写 Python 脚本
创建一个名为 modern_service.py 的文件。
# modern_service.py
import win32serviceutil
import win32service
import win32event
import servicemanager
import time
import logging
import sys
# --- 配置你的服务 ---
SERVICE_NAME = "MyModernPythonService"
SERVICE_DISPLAY_NAME = "My Modern Python Service"
SERVICE_DESCRIPTION = "A more modern way to create a Python service."
class ModernPythonService(win32serviceutil.ServiceFramework):
_svc_name_ = SERVICE_NAME
_svc_display_name_ = SERVICE_DISPLAY_NAME
_svc_description_ = SERVICE_DESCRIPTION
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
self.logger = self._setup_logger()
self.logger.info(f"'{self._svc_display_name_}' 正在启动...")
def _setup_logger(self):
"""配置日志记录到 Windows 事件日志"""
logger = logging.getLogger(SERVICE_NAME)
logger.setLevel(logging.INFO)
# 使用 servicemanager 提供的日志处理器
handler = servicemanager.EventLogHandler()
formatter = logging.Formatter('%(message)s') # 简化格式
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
def SvcStop(self):
"""停止服务"""
self.logger.info("停止请求已收到。")
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
"""服务的主运行循环"""
self.logger.info("主循环已启动。")
while True:
# 检查停止事件
result = win32event.WaitForSingleObject(self.hWaitStop, 5000) # 等待5秒
if result == win32event.WAIT_OBJECT_0:
self.logger.info("停止事件被触发,正在退出循环。")
break
# 你的服务逻辑
self.logger.info("服务正在执行任务...")
# time.sleep(5) # 循环内部已经通过 WaitForSingleObject 实现了等待
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(ModernPythonService)
安装和运行方式与 pywin32 完全相同。
最佳实践和注意事项
- 日志记录是关键: 服务没有控制台,所有调试信息、错误和状态都必须通过 Windows 事件日志 记录,务必实现可靠的日志记录。
- 处理异常: 代码中的任何未捕获异常都会导致服务崩溃,使用
try...except块捕获所有异常,并记录到事件日志中。 - 避免阻塞操作:
SvcDoRun方法中的主循环不应是无限循环,更好的做法是使用while not self.stopped:这样的结构,并在SvcStop中设置一个标志。pywin32的WaitForSingleObject是处理停止事件的推荐方式。 - 安装依赖: 如果你的服务依赖其他 Python 包,必须确保这些包在服务运行的环境中可用,最佳实践是创建一个虚拟环境,然后在该环境中安装所有依赖,并确保 Python 解释器路径正确。
- 以正确的账户运行: 出于安全考虑,尽量避免使用
LocalSystem账户,如果不需要高权限,使用LocalService或NetworkService,如果需要访问网络资源,NetworkService通常是更好的选择。 - 调试服务:
- 最简单的方法: 在开发阶段,不要立即安装为服务,你可以直接运行你的 Python 脚本 (
python my_service.py) 来测试核心逻辑。 - 使用日志: 当服务运行时,通过
services.msc查看事件日志,这是了解服务状态的主要方式。 - 高级调试: 你可以使用
pywin32的win32serviceutil.QueryServiceStatus或sc query命令来检查服务的当前状态。
- 最简单的方法: 在开发阶段,不要立即安装为服务,你可以直接运行你的 Python 脚本 (
| 特性 | pywin32 (原生) |
pywin32-service (封装) |
|---|---|---|
| 易用性 | 中等,需要更多样板代码 | 高,语法更简洁 |
| 控制力 | 高,直接调用 API | 中等,封装了底层细节 |
| 推荐度 | 适合学习原理,或需要高度定制 | 强烈推荐,适合大多数项目 |
| 安装 | pip install pywin32 |
pip install pywin32-service |
对于绝大多数 Python 使用 pywin32-service 库是创建 Windows 服务的最佳选择,因为它在易用性和功能性之间取得了很好的平衡,日志记录和异常处理是编写稳定服务的基石。
