Как на python писать windows сервис?

Пытаюсь по этой статье: https://www.codeproject.com/Articles/1115336/Using... написать windows сервис. В итоге exe с помощью pyinstaller cсобрался успешно, сервис установился, но вот в диспетчере служб у него команды старт/стоп неактивны, если запускать с помощью имяпакета.ехе start то судя по логу, который ведет программа, она запускается 1 раз и завершается. Так же об этом говорит и команда имяпакета.ехе stop которая сообщает о том что сервис недоступен
Вот сам исходник скрипта
import pythoncom
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import time
import sys
import logging, os, glob, re, traceback, sys, fnmatch
from shutil import copyfile


def exists(path):  # Функция проверяет существования файла (указывается полный путь)
    try:
        os.stat(path)
    except OSError:
        logging.error(''.join(traceback.format_exception(*sys.exc_info())))
        return False
    return True


def datatransfer():
        
        # Структура objects в виде:id: исходная папка, маска, папка назначения
        objects = {'IO': ('C://test', 'IO_', 'C://Temp//IO'),
                   }

        ####################################################################


        logging.basicConfig(filename='C://Temp//task.log',
                            format=u'%(filename)s[LINE:%(lineno)d]# %(levelname)-8s [%(asctime)s]  %(message)s',
                            level=logging.DEBUG)

        n = 0  # Инициализация счетчика количества файлов
        for element in objects:
            sourcedir = objects[element][0]  # папка источник
            mask = objects[element][1]  # маска
            destination = objects[element][2]  # назначение

            # Проверка существования каталогов
            if not os.path.exists(sourcedir):
                logging.error('Ошибка : каталог не существует -  {0} правило id {1}'.format(sourcedir, element))
            if not os.path.exists(destination):
                logging.error('Ошибка : каталог не существует -  {0} правило id {1}'.format(destination, element))

            files = glob.glob(os.path.join(sourcedir, '*'))
            for file in files:
                fn = os.path.basename(file)
                if fnmatch.fnmatch(fn, mask):
                    print('Соответствие файла {0} маске {1} Правило id {2}'.format(file, mask, element))
                    try:
                        destination = os.path.join(destination, fn)
                        copyfile(file, destination)
                        if exists(destination):
                            os.remove(file)
                            logging.info('Совпадение : маска {0} файл {1}. Правило id {2}'.format(mask, file, element))
                            logging.info('Успешно : из {0} в {1}. Правило id {2}'.format(file, destination, element))
                            n = n + 1
                        else:
                            logging.error(
                                'После копирования файл {0} не найден в {1}. Правило id {2}'.format(file, destination,
                                                                                                    element))
                    except Exception:
                        logging.error(
                            'Ошибка : маска {0} файл {1} в {2} правило id {3}'.format(mask, file, destination, element))
                        logging.error(''.join(traceback.format_exception(*sys.exc_info())))
        logging.info('Задача завершена. Обработано {0} файлов'.format(n))

        # Удаление лог файла, если тот > 500мб
        log_size = os.path.getsize('task.log') / 1024 / 1024
        if log_size > 500:
            os.remove("task.log")
            logging.basicConfig(filename='task.log',
                                format=u'%(filename)s[LINE:%(lineno)d]# %(levelname)-8s [%(asctime)s]  %(message)s',
                                level=logging.DEBUG)
            logger = logging.getLogger()
            logging.info("Лог файл был очищен")



class DataTransToMongoService(win32serviceutil.ServiceFramework):
    _svc_name_ = 'DataTransToMongoService'
    _svc_display_name_ = 'DataTransToMongoService'

    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.isAlive = False
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)

    def SvcDoRun(self):
        self.isAlive = True
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, ''))
        self.main()
        win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)

    def main(self):
        # i = 0
        while self.isAlive:
            datatransfer()
            time.sleep(5)

            # pass


if __name__ == '__main__':
    if len(sys.argv) == 1:
        servicemanager.Initialize()
        servicemanager.PrepareToHostSingle(DataTransToMongoService)
        servicemanager.StartServiceCtrlDispatcher()
    else:
        win32serviceutil.HandleCommandLine(DataTransToMongoService)
  • Вопрос задан
  • 5143 просмотра
Решения вопроса 1
@shibanovan Автор вопроса
Обрамил вызов datatransfer() в try except - ошибка была в неуказанном пути к файлу task.log
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы