Проблеми з запуском скрипта python як служби

Я використав це запитання щоб навчитися встановлювати моє python-скрипт як службу з ActivePython. Я можу встановити моє скрипт і видалити його, як я очікував би, але проблема полягає в тому, що як тільки я запускаю сценарій, я втрачу можливість зупинити його або видалити його. Це просто працює назавжди, і я не можу позбутися від нього. Відповідь на пов'язане питання згадує перевірку прапору, щоб зупинити сценарій. Чи може хтось пояснити, як це зробити?

Сценарій зараз дуже мало. просто друкує рядки до файлу кожні кілька секунд. Я хочу, щоб він працював, перш ніж перейти до більш складних речей.

import pythoncom
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import time


class AppServerSvc (win32serviceutil.ServiceFramework):
    _svc_name_ = "PythonTest"
    _svc_display_name_ = "Python Test"
    _svc_description_ = "This is a test of installing Python services"

    def __init__(self,args):
        win32serviceutil.ServiceFramework.__init__(self,args)
        self.hWaitStop = win32event.CreateEvent(None,0,0,None)
        socket.setdefaulttimeout(60)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)

    def SvcDoRun(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                          servicemanager.PYS_SERVICE_STARTED,
                          (self._svc_name_,''))
        self.main()

    def main(self):
        i=0
        while True:
            f=open("C:\\hello.txt","a")
            f.write("hello"+str(i)+"\n")
            f.close()
            i=i+1
            time.sleep(5)


if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(AppServerSvc)
2
Я міг би припустити, що цей рецепт ActiveState спрощує написання простих служб Windows значно.
додано Автор ig0774, джерело

2 Відповіді

Звичайно, ви не можете зупинити це, ви застрягли в нескінченному циклі. Замінити:

time.sleep(5)

з цим:

if win32event.WaitForSingleObject(self.hWaitStop, 5000) == win32event.WAIT_OBJECT_0: 
    break

Треба зробити трюк.

5
додано
Дякую. Це працювало. Будь-яка ідея, як позбутися служби, яку я встановив, перш ніж я це виправив?
додано Автор ewok, джерело
Якщо ви відредагували скрипт та відновили службу, новий код повинен перейти. Якщо ви говорите про екземпляри попередньої версії, просто запустіть диспетчер завдань (Ctrl + Shift + Escape) і знищити відповідні процеси; їх слід назвати за вашим сценарієм. Або перезавантажте :)
додано Автор fraca7, джерело
Поки я на це, більш докладне пояснення: метод SvcDoRun фактично запускається у потоці, окремому від імені init . Коли менеджер служби викликає SvcStop, він все ще знаходиться в іншому потоці. Тому ви повинні встановити подію в SvcStop, а також перевірити, чи він встановлений у SvcDoRun, щоб вийти з потоку, коли Windows вам це повідомляє.
додано Автор fraca7, джерело

"Перевірка прапора" означає наявність скрипту (в той час як True loop) шукати щось, майже що завгодно, як сигнал вийти з циклу. Він може перевірити наявність файлу з певним ім'ям і вийти після створення файлу. Поки ви можете вручну або через контрольну програму створити сигнал, служба може шукати той самий сигнал.

Наскільки "не в змозі зупинити це", ви маєте на увазі, що він триває, навіть якщо ви намагаєтесь вбити його за допомогою диспетчера завдань Windows?

0
додано
@ ig0774 правильно
додано Автор ewok, джерело
Імовірно, @ewok означає, що сервіс не може бути зупинений за допомогою панелі керування служб або net stop , і це не так, оскільки з безконечним циклом служба буде просто продовжувати працювати.
додано Автор ig0774, джерело
ІТ КПІ - Python
ІТ КПІ - Python
625 учасників

Канал обговорень про всякі штуки зі світу пайтону. Прохання: 0. мати повагу одне до одного; 1. не матюкатися в сторону людей; 2. не захламляти тред повідомленнями по одному слову;