Наличие нескольких проблем со службой Python для Windows - PullRequest
0 голосов
/ 29 мая 2018

Я проверил, по крайней мере, пару десятков аналогичных дел, которые у меня были, и до сих пор не нашел решения, я надеюсь, что кто-то может пролить немного света, должно быть что-то, чего я здесь упускаю.

Я использую 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

Переменные среды Environment variables

Ошибка средства просмотра событий Event Viewer Error

Средство просмотра событий выводит эту ошибку при каждом запуске, будь то Pythonservice.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.')

При попытке запустить службу из инструмента Services появляется всплывающая ошибка.Я видел и другую ошибку: служба не отвечает вовремя.

Services error when running

Я пытался скомпилировать ее с помощью pyinstaller и nuitka,ошибки одинаковы.Я не уверен в том, что делать дальше, я изменил код, чтобы он соответствовал примерам и решениям, которые я нашел с помощью Google и SO, и почти не понимал, как и почему.

Если у кого-то естьСтолкнулся с этими проблемами раньше, я бы очень признателен за ввод, другие ответы мне пока не помогли.

Позднее редактирование: исправил отступ кода

1 Ответ

0 голосов
/ 06 июня 2018

Это сработало для меня, за исключением различий в коде, в котором я ничего особенного не сделал, после нескольких попыток я смог скомпилировать с помощью pyinstaller и запустить service.exe install без проблем.Есть несколько дополнительных строк регистрации, которые могут не понадобиться людям, но они пригодились при отладке и тестировании.

Большое спасибо всем, кто оставил комментарии, они были чрезвычайно полезны и не могли бы сделать это безВы <3 </p>

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