Windows 的 Python 服务有几个问题 [英] Having several issues with a Python service for Windows

查看:87
本文介绍了Windows 的 Python 服务有几个问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've checked at least a couple of dozen of similar cases to mine and still haven't come up with a solution, I hope someone can shed some light, there's gotta be something I'm missing here.

我正在使用 Python3.6 制作 Windows 服务,如果该服务未运行,则该服务必须运行 .exe 文件.这是.py:

I'm using Python3.6 to make a Windows service, the service has to run a .exe file if it's not running. Here's the .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

I've installed the pywin32 package, added those to the PATH since it was suggested in several solutions, and also copied the .dll from pywin32_system32 to win32

环境变量

事件查看器错误

事件查看器每次运行时都会打印此错误,无论是 python service.py 还是 python service.py start,控制台也会打印:

The Event Viewer prints this error every time I run it be it python service.py, or python service.py start, console also prints this:

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.')

当尝试从服务工具启动服务时,这是弹出的错误.我也看到了另一个错误,关于服务没有及时响应.

When trying to start the service from the Services tool this is the error that pop ups. I've seen the other error too, the oneabout the service not responding in time.

我试过用 pyinstaller 和 nuitka 编译它,错误是一样的.我不确定如何继续,我已经更改了代码以适合我使用 google 和 SO 找到的示例和解决方案,并且对方法和原因知之甚少.

I've tried compiling it with pyinstaller and nuitka, the errors are the same. I'm unsure as to how to proceed, I've changed the code to fit examples and solutions I've found using google and SO, and have gained little understanding of the hows and whys.

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

If anyone has faced these issues before, I'd really appreciate the input, other answers haven't helped me so far.

后期修复了代码缩进

推荐答案

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

This ended up working for me, other than the difference in the code I didn't really do anything special, after a few tries I got to compile with pyinstaller and run service.exe install without issues. There are some extra logging lines that people might not need, but they came in handy when debugging and testing.

非常感谢留下评论的每个人,他们非常有帮助,没有你们就无法完成<3

Thanks a lot to the everyone who left comments, they were extremely helpful and couldn't have done it without you <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)

这篇关于Windows 的 Python 服务有几个问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆