Как запустить сценарий Python как службу в Windows?

python windows cross-platform

173114 просмотра

9 ответа

13298 Репутация автора

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

В настоящее время я нацелен на Python и Django как технологии для реализации этого сервиса. Я почти уверен, что я понимаю, как демонизировать программу Python в Linux. Тем не менее, это необязательный элемент спецификации, который система должна поддерживать Windows. У меня мало опыта программирования Windows, и у меня нет опыта работы с службами Windows.

Можно ли запускать программы Python в качестве службы Windows (т. Е. Запускать ее автоматически без входа пользователя)? Я не обязательно буду реализовывать эту часть, но мне нужно приблизительное представление о том, как это будет сделано, чтобы решить, следует ли разрабатывать эти строки.

Редактировать: Спасибо за все ответы до сих пор, они довольно полные. Я хотел бы узнать еще одно: как Windows знает о моем сервисе? Могу ли я управлять им с помощью родных утилит Windows? Каков эквивалент старта / остановки скрипта в /etc/init.d?

Автор: Hanno Fietz Источник Размещён: 28.08.2008 02:28

Ответы (9)


227 плюса

6392 Репутация автора

Решение

Да, ты можешь. Я делаю это, используя библиотеки pythoncom, входящие в состав ActivePython, или их можно установить с помощью pywin32 (расширения для Python для Windows).

Это простой скелет для простого обслуживания:

import win32serviceutil
import win32service
import win32event
import servicemanager
import socket


class AppServerSvc (win32serviceutil.ServiceFramework):
    _svc_name_ = "TestService"
    _svc_display_name_ = "Test Service"

    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):
        pass

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(AppServerSvc)

Ваш код будет идти в main()методе - обычно с каким-то бесконечным циклом, который может быть прерван проверкой флага, который вы задали в SvcStopметоде

Автор: Ricardo Reyes Размещён: 28.08.2008 02:39

24 плюса

3263 Репутация автора

Есть несколько альтернатив для установки в качестве службы практически любого исполняемого файла Windows.

Способ 1: Используйте instsrv и srvany из rktools.exe

Для Windows Home Server или Windows Server 2003 (также работает с WinXP) средства набора ресурсов Windows Server 2003 поставляются с утилитами, которые можно использовать в тандеме для этого: instsrv.exe и srvany.exe . См. Эту статью KB137890 Microsoft KB для получения подробной информации о том, как использовать эти утилиты.

Для Windows Home Server существует большая удобная оболочка для этих утилит с меткой « Any Service Installer ».

Способ 2. Использование ServiceInstaller для Windows NT

Существует еще одна альтернатива, использующая ServiceInstaller для Windows NT ( доступна для загрузки ) с доступными инструкциями python . В отличие от имени, он работает как с Windows 2000, так и с Windows XP. Ниже приведены некоторые инструкции по установке скрипта python в качестве службы.

Установка скрипта Python

Запустите ServiceInstaller для создания новой службы. (В этом примере предполагается, что python установлен в c: \ python25)

Service Name  : PythonTest
Display Name : PythonTest 
Startup : Manual (or whatever you like)
Dependencies : (Leave blank or fill to fit your needs)
Executable : c:\python25\python.exe
Arguments : c:\path_to_your_python_script\test.py
Working Directory : c:\path_to_your_python_script

После установки откройте апплет служб «Панель управления», выберите и запустите службу PythonTest.

После моего первоначального ответа я заметил, что были тесно связанные вопросы и ответы, уже размещенные на SO. Смотрите также:

Можно ли запустить скрипт Python в качестве службы (в Windows)? Как?

Как заставить Windows знать о службе, которую я написал на Python?

Автор: popcnt Размещён: 28.02.2009 08:30

31 плюса

582 Репутация автора

Хотя пару недель назад я поддержал выбранный ответ, тем временем я больше боролся с этой темой. Похоже, что иметь специальную установку Python и использовать специальные модули для запуска скрипта как службы - это просто неправильный путь. Как насчет мобильности и тому подобного?

Я наткнулся на замечательного Менеджера обслуживания , не связанного с отсосом , который сделал его очень простым и разумным для работы с Windows Services. Я понял, что, поскольку я мог передавать параметры установленному сервису, я мог бы просто выбрать свой исполняемый файл Python и передать свой сценарий в качестве опции.

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

Автор: mknaf Размещён: 28.07.2014 01:41

17 плюса

305 Репутация автора

Самый простой способ добиться этого - использовать собственную команду sc.exe:

sc create PythonApp binPath= "C:\Python34\Python.exe --C:\tmp\pythonscript.py"
  1. https://technet.microsoft.com/en-us/library/cc990289(v=ws.11).aspx
  2. создание сервиса с помощью sc.exe; как передать параметры контекста
Автор: pyOwner Размещён: 07.12.2016 12:23

-2 плюса

11 Репутация автора

pysc: диспетчер управления сервисом на Python

Пример скрипта для запуска в качестве сервиса, взятого с pythonhosted.org :

from xmlrpc.server import SimpleXMLRPCServer

from pysc import event_stop


class TestServer:

    def echo(self, msg):
        return msg


if __name__ == '__main__':
    server = SimpleXMLRPCServer(('127.0.0.1', 9001))

    @event_stop
    def stop():
        server.server_close()

    server.register_instance(TestServer())
    server.serve_forever()

Создание и запуск сервиса

import os
import sys
from xmlrpc.client import ServerProxy

import pysc


if __name__ == '__main__':
    service_name = 'test_xmlrpc_server'
    script_path = os.path.join(
        os.path.dirname(__file__), 'xmlrpc_server.py'
    )
    pysc.create(
        service_name=service_name,
        cmd=[sys.executable, script_path]
    )
    pysc.start(service_name)

    client = ServerProxy('http://127.0.0.1:9001')
    print(client.echo('test scm'))

Остановка и удаление службы

import pysc

service_name = 'test_xmlrpc_server'

pysc.stop(service_name)
pysc.delete(service_name)
pip install pysc
Автор: Seliverstov Maksim Размещён: 03.03.2017 08:29

9 плюса

91 Репутация автора

Пошаговое объяснение, как заставить его работать:

1- Сначала создайте файл python в соответствии с основным скелетом, упомянутым выше. И сохраните его на пути, например: «c: \ PythonFiles \ AppServerSvc.py»

import win32serviceutil
import win32service
import win32event
import servicemanager
import socket


class AppServerSvc (win32serviceutil.ServiceFramework):
    _svc_name_ = "TestService"
    _svc_display_name_ = "Test Service"


    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):
        # Your business logic or call to any class should be here
        # this time it creates a text.txt and writes Test Service in a daily manner 
        f = open('C:\\test.txt', 'a')
        rc = None
        while rc != win32event.WAIT_OBJECT_0:
            f.write('Test Service  \n')
            f.flush()
            # block for 24*60*60 seconds and wait for a stop event
            # it is used for a one-day loop
            rc = win32event.WaitForSingleObject(self.hWaitStop, 24 * 60 * 60 * 1000)
        f.write('shut down \n')
        f.close()

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(AppServerSvc)

2 - На этом этапе мы должны зарегистрировать наш сервис.

Запустите командную строку как администратор и введите:

sc create TestService binpath = "C: \ Python36 \ Python.exe c: \ PythonFiles \ AppServerSvc.py" DisplayName = "TestService" start = auto

первый аргумент binpath - это путь к python.exe

второй аргумент binpath - это путь к вашему файлу python, который мы создали уже

Не пропустите, что вы должны поместить одно место после каждого знака « = ».

Тогда, если все в порядке, вы должны увидеть

[SC] CreateService УСПЕХ

Теперь ваша служба python установлена ​​как служба Windows. Вы можете увидеть его в Service Manager и в реестре:

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ TestService

3- Хорошо. Вы можете начать свою службу в сервис-менеджере.

Вы можете выполнить каждый файл python, который предоставляет этот сервисный скелет.

Автор: Seckin Sanli Размещён: 29.06.2017 08:37

11 плюса

111 Репутация автора

Самый простой способ - использовать: NSSM - диспетчер служб несвязывания:

1 - скачать на https://nssm.cc/download

2 - установить программу python в качестве службы: Win prompt as admin

c:> nssm.exe установить WinService

3 - На консоли NSSM:

путь: C: \ Python27 \ Python27.exe

Каталог автозагрузки: C: \ Python27

Аргументы: c: \ WinService.py

4 - проверить созданные службы на services.msc

Автор: Adriano R P L Размещён: 27.09.2017 02:05

0 плюса

302 Репутация автора

Я начал работать как сервис с pywin32 .

Все было хорошо, но я столкнулся с проблемой, что служба не смогла начать работу в течение 30 секунд (время ожидания по умолчанию для Windows) при запуске системы. Это было важно для меня, потому что запуск Windows происходил одновременно на нескольких виртуальных машинах, размещенных на одной физической машине, а загрузка IO была огромной. Сообщения об ошибках:

Error 1053: The service did not respond to the start or control request in a timely fashion.

Error 7009: Timeout (30000 milliseconds) waiting for the <ServiceName> service to connect.

Я много сражался с pywin, но в итоге использовал NSSM, как это было предложено в этом ответе . Было очень легко мигрировать к нему.

Автор: flam3 Размещён: 12.10.2018 01:07

0 плюса

1601 Репутация автора

Принятый ответ использует win32serviceutilработы, но усложняется и усложняет отладку. С ПОМОЩЬЮ FAR проще использовать NSSM ( диспетчер служб несвязывания) . Вы просто берете обычную программу python, а затем используете NSSM для установки в качестве службы менее чем за минуту:

Из командной строки с повышенными правами (admin) вы запустите nssm.exe install NameOfYourServiceи заполните следующие параметры:

  • path : (путь к python.exe, например C:\Python27\Python.exe)
  • Аргументы : (путь к вашему скрипту python, например c:\path\to\program.py)

Кстати, если ваша программа печатает полезные сообщения, которые вы хотите сохранить в файле журнала, NSSM также может справиться с этим и многое другое для вас.

Автор: ndemou Размещён: 10.11.2018 03:52
Вопросы из категории :
32x32