Windows 的 Python 服务有几个问题
Having several issues with a Python service for Windows
我已经检查了至少几十个与我相似的案例,但仍然没有找到解决方案,我希望有人能给出一些启示,我一定有什么遗漏的。
我正在使用 Python3.6 创建一个 Windows 服务,该服务必须 运行 一个 .exe 文件,如果它不是 运行ning。这是 .py:
import win32service
import win32serviceutil
import win32api
import win32con
import win32event
import win32evtlogutil
import psutil
import subprocess
import os, sys, string, time
import servicemanager
class SLAAgent (win32serviceutil.ServiceFramework):
_svc_name_ = "SLAAgent"
_svc_display_name_ = "SLAAgent"
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
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_, ''))
self._logger.info("Service Is Starting")
main(self)
def main(self):
while self.isAlive:
rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
# Check to see if self.hWaitStop happened
if rc == win32event.WAIT_OBJECT_0:
servicemanager.LogInfoMsg("SLAAService has stopped") #For Event Log
break
else:
try:
s = subprocess.check_output('tasklist', shell=True)
if "SLA_Client.exe" in s:
pass
else:
pass
#execfile("SLA_Client.exe") #Execute the script
except:
pass
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(SLAAgent)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(SLAAgent)
我已经安装了 pywin32 包,将它们添加到 PATH 中,因为它在几个解决方案中被建议,并且还将 .dll 从 pywin32_system32 复制到 win32
环境变量
事件查看器错误
每次我 运行 时事件查看器都会打印此错误,无论是 python service.py 还是 python service.py 启动,控制台也会打印此错误:
python SLA_Agent.py
Traceback (most recent call last):
File "SLA_Agent.py", line 56, in <module>
servicemanager.StartServiceCtrlDispatcher()
pywintypes.error: (1063, 'StartServiceCtrlDispatcher', 'The service process
could not connect to the service controller.')
尝试从“服务”工具启动服务时,会弹出此错误。我也看到了另一个错误,关于服务没有及时响应的错误。
我试过用pyinstaller和nuitka编译,错误都是一样的。我不确定如何继续,我已经更改了代码以适应我使用 google 和 SO 找到的示例和解决方案,并且对方法和原因知之甚少。
如果有人以前遇到过这些问题,我将非常感谢您的意见,到目前为止其他答案对我没有帮助。
后期编辑:修复了代码缩进
这最终对我有用,除了代码上的差异我没有做任何特别的事情,经过几次尝试我不得不使用 pyinstaller 和 运行 service.exe install
编译问题。有一些人们可能不需要的额外日志行,但在调试和测试时它们派上用场了。
非常感谢所有留下评论的人,他们非常有帮助,没有你们就不可能完成<3
import win32service, win32serviceutil, win32api, win32con, win32event, win32evtlogutil
import psutil
import subprocess
import os, sys, string, time, socket, signal
import servicemanager
class Service (win32serviceutil.ServiceFramework):
_svc_name_ = "Service"
_svc_display_name_ = "Service"
def __init__(self,args):
win32serviceutil.ServiceFramework.__init__(self, *args)
self.log('Service Initialized.')
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def log(self, msg):
servicemanager.LogInfoMsg(str(msg))
def sleep(self, sec):
win32api.Sleep(sec*1000, True)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
self.stop()
self.log('Service has stopped.')
win32event.SetEvent(self.stop_event)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
try:
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.log('Service is starting.')
self.main()
win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,servicemanager.PYS_SERVICE_STARTED,(self._svc_name_, ''))
except Exception as e:
s = str(e);
self.log('Exception :'+s)
self.SvcStop()
def stop(self):
self.runflag=False
try:
#logic
except Exception as e:
self.log(str(e))
def main(self):
self.runflag=True
while self.runflag:
rc = win32event.WaitForSingleObject(self.stop_event, 24*60*60)
# Check to see if self.hWaitStop happened
if rc == win32event.WAIT_OBJECT_0:
self.log("Service has stopped")
break
else:
try:
#logic
except Exception as e:
self.log(str(e))
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(Service)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(Service)
我已经检查了至少几十个与我相似的案例,但仍然没有找到解决方案,我希望有人能给出一些启示,我一定有什么遗漏的。
我正在使用 Python3.6 创建一个 Windows 服务,该服务必须 运行 一个 .exe 文件,如果它不是 运行ning。这是 .py:
import win32service
import win32serviceutil
import win32api
import win32con
import win32event
import win32evtlogutil
import psutil
import subprocess
import os, sys, string, time
import servicemanager
class SLAAgent (win32serviceutil.ServiceFramework):
_svc_name_ = "SLAAgent"
_svc_display_name_ = "SLAAgent"
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
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_, ''))
self._logger.info("Service Is Starting")
main(self)
def main(self):
while self.isAlive:
rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
# Check to see if self.hWaitStop happened
if rc == win32event.WAIT_OBJECT_0:
servicemanager.LogInfoMsg("SLAAService has stopped") #For Event Log
break
else:
try:
s = subprocess.check_output('tasklist', shell=True)
if "SLA_Client.exe" in s:
pass
else:
pass
#execfile("SLA_Client.exe") #Execute the script
except:
pass
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(SLAAgent)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(SLAAgent)
我已经安装了 pywin32 包,将它们添加到 PATH 中,因为它在几个解决方案中被建议,并且还将 .dll 从 pywin32_system32 复制到 win32
环境变量
事件查看器错误
每次我 运行 时事件查看器都会打印此错误,无论是 python service.py 还是 python service.py 启动,控制台也会打印此错误:
python SLA_Agent.py
Traceback (most recent call last):
File "SLA_Agent.py", line 56, in <module>
servicemanager.StartServiceCtrlDispatcher()
pywintypes.error: (1063, 'StartServiceCtrlDispatcher', 'The service process
could not connect to the service controller.')
尝试从“服务”工具启动服务时,会弹出此错误。我也看到了另一个错误,关于服务没有及时响应的错误。
我试过用pyinstaller和nuitka编译,错误都是一样的。我不确定如何继续,我已经更改了代码以适应我使用 google 和 SO 找到的示例和解决方案,并且对方法和原因知之甚少。
如果有人以前遇到过这些问题,我将非常感谢您的意见,到目前为止其他答案对我没有帮助。
后期编辑:修复了代码缩进
这最终对我有用,除了代码上的差异我没有做任何特别的事情,经过几次尝试我不得不使用 pyinstaller 和 运行 service.exe install
编译问题。有一些人们可能不需要的额外日志行,但在调试和测试时它们派上用场了。
非常感谢所有留下评论的人,他们非常有帮助,没有你们就不可能完成<3
import win32service, win32serviceutil, win32api, win32con, win32event, win32evtlogutil
import psutil
import subprocess
import os, sys, string, time, socket, signal
import servicemanager
class Service (win32serviceutil.ServiceFramework):
_svc_name_ = "Service"
_svc_display_name_ = "Service"
def __init__(self,args):
win32serviceutil.ServiceFramework.__init__(self, *args)
self.log('Service Initialized.')
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def log(self, msg):
servicemanager.LogInfoMsg(str(msg))
def sleep(self, sec):
win32api.Sleep(sec*1000, True)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
self.stop()
self.log('Service has stopped.')
win32event.SetEvent(self.stop_event)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
try:
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.log('Service is starting.')
self.main()
win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,servicemanager.PYS_SERVICE_STARTED,(self._svc_name_, ''))
except Exception as e:
s = str(e);
self.log('Exception :'+s)
self.SvcStop()
def stop(self):
self.runflag=False
try:
#logic
except Exception as e:
self.log(str(e))
def main(self):
self.runflag=True
while self.runflag:
rc = win32event.WaitForSingleObject(self.stop_event, 24*60*60)
# Check to see if self.hWaitStop happened
if rc == win32event.WAIT_OBJECT_0:
self.log("Service has stopped")
break
else:
try:
#logic
except Exception as e:
self.log(str(e))
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(Service)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(Service)