Python3.6 Windows服务开发遇1063错误求助
解决Windows Python服务启动错误1063及进程监控问题
我来帮你排查这个Windows服务启动失败的问题,你遇到的pywintypes.error: (1063, 'StartServiceCtrlDispatcher', 'The service process could not connect to the service controller.')错误,大多是因为服务初始化阶段出现异常,导致进程无法和服务控制器建立连接。咱们先从代码里的问题入手,再讲部署注意事项:
代码里的关键问题及修正
你的代码里有几个明显的问题,会直接导致服务启动失败:
1. 缺失依赖与未定义变量
- 代码中使用了
socket.setdefaulttimeout(60)但没有导入socket模块 self._logger.info中的_logger从未初始化,会抛出异常main方法里用了self.timeout但没定义这个变量SvcDoRun中调用main(self)是错误的,应该调用类自身的方法self.main()
2. 进程检查与启动的问题
tasklist的输出在Windows下是GBK编码,直接用字符串比较可能出现乱码匹配失败- 注释掉的
execfile是Python2的函数,Python3中需要用subprocess启动外部程序 - 启动exe时最好用绝对路径,避免服务默认工作目录找不到程序
修正后的完整代码
import win32service import win32serviceutil import win32api import win32con import win32event import win32evtlogutil import psutil import subprocess import os, sys, string, time import servicemanager import socket # 补上缺失的socket导入 class SLAAgent (win32serviceutil.ServiceFramework): _svc_name_ = "SLAAgent" _svc_display_name_ = "SLAAgent" # 定义进程检查间隔(毫秒),这里设置为5秒 timeout = 5000 def __init__(self, args): win32serviceutil.ServiceFramework.__init__(self, args) self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) socket.setdefaulttimeout(60) self.isAlive = True def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.hWaitStop) self.isAlive = False servicemanager.LogInfoMsg("SLAAgent has stopped") def SvcDoRun(self): self.ReportServiceStatus(win32service.SERVICE_START_PENDING) self.ReportServiceStatus(win32service.SERVICE_RUNNING) servicemanager.LogMsg( servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, '') ) # 用servicemanager日志替代未初始化的logger servicemanager.LogInfoMsg("Service Is Starting") self.main() # 修正方法调用方式 def main(self): # 替换成SLA_Client.exe的绝对路径,比如C:\\Apps\\SLA_Client.exe client_exe_path = "SLA_Client.exe" while self.isAlive: rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout) if rc == win32event.WAIT_OBJECT_0: break else: try: # 处理tasklist的编码问题,避免乱码 s = subprocess.check_output('tasklist', shell=True, encoding='gbk') if "SLA_Client.exe" not in s: servicemanager.LogInfoMsg("Starting SLA_Client.exe...") # 启动程序时隐藏控制台窗口 subprocess.Popen( client_exe_path, creationflags=subprocess.CREATE_NO_WINDOW ) except Exception as e: # 把异常记录到事件查看器,方便排查 servicemanager.LogErrorMsg(f"Error checking/starting process: {str(e)}") if __name__ == '__main__': if len(sys.argv) == 1: servicemanager.Initialize() servicemanager.PrepareToHostSingle(SLAAgent) servicemanager.StartServiceCtrlDispatcher() else: win32serviceutil.HandleCommandLine(SLAAgent)
部署与调试步骤
- 安装服务:打开管理员权限的命令提示符,切换到脚本所在目录,运行:
python SLA_Agent.py install - 启动服务:
net start SLAAgent - 调试模式:如果需要排查问题,用调试模式在控制台运行,能直接看到错误输出:
python SLA_Agent.py debug - 权限注意事项:Windows服务默认用
Local System账户,确保该账户有权限启动SLA_Client.exe;如果程序需要特定权限,可以在服务属性里修改登录账户为有足够权限的用户。
额外优化建议
- 用
psutil替代tasklist检查进程,更可靠且避免编码问题:def is_process_running(process_name): for proc in psutil.process_iter(['name']): if proc.info['name'] == process_name: return True return False - 编译打包时,PyInstaller要加上隐藏导入参数确保依赖被打包:
pyinstaller --onefile --hidden-import win32serviceutil --hidden-import win32service --hidden-import win32event SLA_Agent.py
内容的提问来源于stack exchange,提问作者danks
相关产品推荐
相关产品推荐

