Вопрос-Ответ

How do you run a Python script as a service in Windows?

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

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

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

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

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

Переведено автоматически
Ответ 1

Да, вы можете. Я делаю это с помощью библиотек 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 методе

Ответ 2

Самый простой способ - использовать: NSSM - диспетчер служб без отсоса. Просто скачайте и распакуйте в папку по вашему выбору. Это автономная утилита, объемом около 300 КБ (намного меньше, чем установка всего пакета pywin32 только для этой цели), и никакой "установки" не требуется. Zip содержит 64-разрядную и 32-разрядную версии утилиты. Любая из них должна хорошо работать в текущих системах (вы можете использовать 32-разрядную версию для управления службами в 64-разрядных системах).

Подход с графическим интерфейсом

1 - установите программу python как службу. Откройте приглашение Win от имени администратора

c:\>nssm.exe install WinService

2 - В графической консоли NSSMs:

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

Каталог запуска: C:\Python27

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

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

Подход к написанию сценариев (без графического интерфейса)

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

Для удобства команды описаны здесь, просто обозначая утилиту как nssm.exe. Желательно, однако, ссылаться на него более явно в скриптах с указанием его полного пути c:\path\to\nssm.exe, поскольку это автономный исполняемый файл, который может располагаться по закрытому пути, о котором система не знает.

1. Установите службу

Вы должны указать имя службы, путь к соответствующему исполняемому файлу Python и путь к скрипту:

nssm.exe install ProjectService "c:\path\to\python.exe" "c:\path\to\project\app\main.py"

Подробнее:

nssm.exe install ProjectService 
nssm.exe set ProjectService Application "c:\path\to\python.exe"
nssm.exe set ProjectService AppParameters "c:\path\to\project\app\main.py"

В качестве альтернативы вы можете захотеть, чтобы ваше приложение Python запускалось как модуль Python. Один из простых подходов - сообщить nssm, что ему необходимо перейти в соответствующий начальный каталог, как вы бы сделали сами при запуске из командной оболочки.:

nssm.exe install ProjectService "c:\path\to\python.exe" "-m app.main"
nssm.exe set ProjectService AppDirectory "c:\path\to\project"

Такой подход хорошо работает с виртуальными средами и автономное (встроенный) Питон устанавливается. Просто убедитесь, что правильно решены любые проблемы, пути в тех средах, с обычными методами. в nssm есть способ устанавливать переменные среды (например, PYTHONPATH), если это необходимо, а также может запускать пакетные скрипты.

2. Чтобы запустить службу

nssm.exe start ProjectService 

3. Чтобы остановить службу

nssm.exe stop ProjectService

4. Чтобы удалить службу, укажите confirm параметр, позволяющий пропустить интерактивное подтверждение.

nssm.exe remove ProjectService confirm
Ответ 3

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

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

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

Ответ 4

Самый простой способ добиться этого - использовать собственную команду 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 как передать параметры контекста?

python windows