【问题标题】:Having several issues with a Python service for WindowsWindows 的 Python 服务有几个问题
【发布时间】:2018-05-29 18:32:01
【问题描述】:

我已经检查了至少几十个与我类似的案例,但仍然没有想出解决方案,我希望有人能解释一下,这里一定是我遗漏了一些东西。

我正在使用 Python3.6 制作 Windows 服务,如果服务没有运行,则必须运行 .exe 文件。这是.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 start 时都会打印此错误,控制台也会打印此错误:

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 找到的示例和解决方案,并且对方法和原因知之甚少。

如果有人以前遇到过这些问题,我非常感谢您的意见,到目前为止,其他答案对我没有帮助。

后期编辑:修复代码缩进

【问题讨论】:

  • 我假设if __name__ == '__main__': 下的代码应该缩进。
  • 使用pyinstaller 创建.exe -- 然后使用my_service.exe debug 运行该服务并查看它在您的控制台中执行。如果可行,请执行my_service.exe install 安装该服务。您应该在服务列表中看到它。然后my_service.exe start 启动它(或使用服务 gui)。很确定它不相关,但我需要做的一件常见事情是将 win32timezone 指定为 pyinstaller 的隐藏导入。
  • @sytech 我会尝试并很快通知您,但这几乎是我在 MartinEvans 之前所做的事情,它应该缩进到类 SLAAgent 的同一级别,否则 PrepareToHostSingle 将抱怨未定义 SLAAgent。
  • 我相信你已经看过这个,因为代码看起来很像,但我使用这个ryrobes.com/python/running-python-scripts-as-a-windows-service 几乎是为了在 Windows 7 和 python2 中成功运行服务。另外,可能要添加pywin32 标签。我敢肯定人们有时会搜索该标签以尝试回答问题。
  • @DanielF。是的,我确实找到了该代码并在此基础上构建了一些代码。我一定是做错了什么,今天我有机会在另一台没有安装 Python 的计算机上尝试该服务

标签: python windows service pyinstaller pywin32


【解决方案1】:

这最终对我有用,除了代码的差异我并没有真正做任何特别的事情,经过几次尝试后,我使用 pyinstaller 编译并运行 service.exe install 没有问题。有一些人们可能不需要的额外日志记录行,但在调试和测试时会派上用场。

非常感谢所有离开 cmets 的人,他们非常乐于助人,没有你们就无法做到

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 2021-01-08
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多