Я рисую архитектуру для набора программ, которые совместно используют различные взаимосвязанные объекты, хранящиеся в базе данных. Я хочу, чтобы одна из программ выступала в качестве службы, которая обеспечивает интерфейс более высокого уровня для операций над этими объектами, а другие программы — для доступа к объектам через эту службу.
В настоящее время я нацелен на создание Python и Django как технологий для реализации этого сервиса. Я почти уверен, что я понимаю, как демонизировать программу Python в Linux. Тем не менее, это необязательный элемент спецификации, который система должна поддерживать Windows. У меня мало опыта программирования Windows, и у меня нет опыта работы с службами Windows.
Можно ли запускать программы Python в качестве службы Windows (т.е. запускать ее автоматически без входа пользователя)? Я не обязательно буду реализовывать эту часть, но мне нужно понять, как это будет сделано для того, чтобы решить, следует ли разрабатывать эти строки. Изменить: Спасибо за все ответы до сих пор, они довольно полные.
Уроки C# – Создаём свою службу Windows
Я хотел бы узнать еще одно: Как Windows знает о моем сервисе? Могу ли я управлять им с помощью родных утилит Windows? Что эквивалентно помещению start/stop script в/etc/init.d?
Hanno Fietz 28 авг. 2008, в 13:30
Поделиться
Проверьте этот шаблон службы Windows, он использует win32service API .
CMS 28 фев. 2009, в 05:52
Поделиться:
cross-platform
7 ответов
Лучший ответ
Да, вы можете. Я использую библиотеки 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 авг. 2008, в 15:58
Поделиться
После кодирования, как я могу сказать Windows, чтобы запустить это как службу?
Kit 19 сен. 2010, в 23:44
Ricardo Reyes 22 сен. 2010, в 12:29
python my_script_as_service.py install ?
Kit 22 сен.
2010, в 17:12
Скрипт отсутствует «импорта сокета» в верхней части. Вы также можете добавить « svc_description », чтобы изменить описание сервиса. Спасибо, это спасло меня от охоты!
Как восстановить службы по умолчанию Windows 10
David Newcomb 13 янв. 2011, в 18:05
Вы особо упоминаете pythoncom и импортируете его в свой пример кода. Проблема в том, что вы никогда не используете pythoncom где-либо в своем примере кода, вы только импортируете его. Зачем упоминать об этом, а потом не показывать его использование?
Buttons840 12 апр. 2011, в 17:56
Почему для socket.setdefaulttimeout(60) есть? Нужно ли это для какой-либо службы или просто случайно скопировано из какой-либо существующей службы? 🙂
Timur 10 сен. 2011, в 12:42
Можете ли вы объяснить, что вы подразумеваете под «проверкой флага», чтобы остановить службу? Как ты это делаешь?
ewok 28 окт. 2011, в 14:30
javawizard 24 июль 2012, в 01:36
ThatAintWorking 10 авг. 2013, в 22:28
Это выглядит великолепно, я заменил пустой основной цикл с записью в файл некоторого текста. Файл создан, но остается пустым, есть идеи, почему? Более того, когда я запускаю службу, я получаю Starting service TestService , а если я делаю следующее, я делаю остановку службы, я получаю Службу остановки при Error stopping service: The service has not been started. (1062) , что не так?
e271p314 02 дек. 2013, в 12:42
n611x007 09 июль 2014, в 09:00
Удаление службы, похоже, не работает для меня. Служба всегда заканчивается в состоянии STOP_PENDING или подобном и никогда не завершает работу, пока я не убью его с помощью sc queryex
mknaf 28 июль 2014, в 14:00
chrisumbel.com/article/windows_services_in_python Это похожий пример, но более полный
csprabala 27 май 2015, в 15:55
Kounavi 02 окт. 2015, в 03:14
AdrianBoeh 29 дек. 2015, в 22:11
Mahdi 24 март 2017, в 22:21
Я использовал этот код как есть и смог установить службу с помощью python test_service.py install но когда я пытаюсь запустить службу, используя python test_service.py start или NET START TestService она возвращает сообщение «Служба не отвечает на функция управления », нужно ли что-то реализовывать в методе SvcDoRun ?
Some Guy 04 май 2017, в 14:57
576i 09 окт. 2017, в 20:03
Thomas Ahle 28 нояб. 2017, в 16:03
pywintypes.error: (1053, ‘StartService’, ‘Служба не ответила на запрос запуска или управления во время своевременного обращения.’)
alireza 18 март 2018, в 07:27
Это не работает для Python 3.7
pajarnas 19 март 2019, в 19:03
Показать ещё 19 комментариев
Хотя я выделил выбранный ответ пару недель назад, тем временем я больше боролся с этой темой. Похоже, что у вас есть специальная установка на Python и использование специальных модулей для запуска script, поскольку сервис — это просто неправильный путь. Как насчет переносимости и т.д.
Я наткнулся на замечательный Non-sucking Service Manager, который сделал его очень простым и разумным для работы с Windows Services. Я понял, что, поскольку я мог передавать параметры установленному сервису, я мог бы просто выбрать исполняемый файл Python и передать мой script в качестве опции.
Я еще не пробовал это решение, но я сделаю это прямо сейчас и обновил этот пост в процессе. Я также заинтересован в использовании virtualenvs в Windows, поэтому я мог бы придумать учебник рано или поздно и ссылку на него здесь.
mknaf 28 июль 2014, в 15:09
Поделиться
При удаче? Я создаю очень простой сайт для клиента, и мне не нужно использовать весь стек Apache. Кроме того, создание службы само по себе звучало как приглашение для неприятностей, как я прочитал из других комментариев.
Jaran 17 авг. 2014, в 12:25
Да, это работает, и это очень легко сделать. Вы просто даете путь и аргументы для сценария. Я смог заставить мой работать без консоли на тот случай, если кто-то каким-нибудь образом получит окно консоли.
kmcguire 09 сен. 2014, в 13:44
Хотя это, очевидно, работает, есть и другие трудности, особенно когда вам «не нужно использовать весь стек Apache»: например, gunicorn еще не работает в Windows, что на самом деле было для меня показателем.
mknaf 09 сен. 2014, в 19:15
Хитрость заключается в том, чтобы запустить python.exe как сервис и ваш скрипт на python в качестве параметра: например, «nssm install MyServiceName c: python27 python.exe c: temp myscript.py»
poleguy 23 нояб. 2015, в 23:22
Работает отлично! В системе с несколькими виртуальными средами путь может ссылаться на исполняемый файл интерпретатора Python в каталоге Scripts требуемой виртуальной среды. Кажется, что new-service в PowerShell должен быть в состоянии сделать это, но запуск (и мониторинг) скрипта как сервиса, очевидно, включает в себя гораздо больше деталей, о которых nssm очень хорошо заботится.
Fred Schleifer 22 дек. 2015, в 07:23
Показать ещё 3 комментария
Существует несколько альтернатив для установки в качестве службы практически любого исполняемого файла Windows.
Способ 1: Использовать instrrv и srvany из rktools.exe
Для Windows Home Server или Windows Server 2003 (также работает с WinXP), Windows Server 2003 Resource Kit Tools поставляется с утилит, которые могут для этого используется тандема, называемая instsrv.exe и srvany.exe. Подробнее о том, как использовать эти утилиты, см. В статье Microsoft KB KB137890.
Для Windows Home Server существует большая удобная оболочка для этих утилит с меткой «» Любой установщик услуг».
Способ 2. Использовать ServiceInstaller для Windows NT
Существует другая альтернатива, использующая ServiceInstaller для Windows NT ( скачать можно здесь) с доступные инструкции python. В отличие от имени, он работает как с Windows 2000, так и с Windows XP. Ниже приведены некоторые инструкции по установке python script в качестве службы.
Установка Python script
Запустите 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:python25python.exe Arguments : c:path_to_your_python_scripttest.py Working Directory : c:path_to_your_python_script
После установки откройте Control Апплет Panel Services, выберите и запустите службу PythonTest.
После моего первоначального ответа я заметил, что были тесно связанные Q противоречить» названию, по крайней мере, в речи программистов. Это просто относится к « архитектуре NT», в отличие от « бренда NT». Тем не менее, согласно разговору в Википедии, это подлежит обсуждению, поскольку «это не официальный термин Microsoft», но тем не менее существует традиция с таким типом мышления.
n611x007 09 июль 2014, в 08:30
Показать ещё 2 комментария
Самый простой способ добиться этого — использовать собственную команду sc.exe:
sc create PythonApp binPath= «C:Python34Python.exe —C:tmppythonscript.py»
- https://technet.microsoft.com/en-us/library/cc990289(v=ws.11).aspx
- создание сервиса с помощью sc.exe;как передать параметры контекста
pyOwner 07 дек. 2016, в 13:56
Поделиться
Самый простой способ — использовать: NSSM — диспетчер служб несвязывания:
2 — установить программу python в качестве службы: Win prompt as admin
c:> nssm.exe установить WinService
3 — На консоли NSSM:
Каталог автозагрузки: C:Python27
4 — проверить созданные службы на services.msc
Adriano R P L 27 сен. 2017, в 15:53
Поделиться
Пошаговое объяснение, как заставить его работать:
1- Сначала создайте файл python в соответствии с основным скелетом, упомянутым выше. И сохраните его на пути, например: «c:PythonFilesAppServerSvc.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 создать TestService binpath = «C:Python36Python.exe c:PythonFilesAppServerSvc.py» DisplayName = «TestService» start = auto
первым аргументом binpath является путь файла python.exe
Второй аргумент binpath — это путь к вашему файлу python, который мы уже создали
Не пропустите, что вы должны поместить одно место после каждого знака < =.
Тогда, если все в порядке, вы должны увидеть
Теперь ваша служба python установлена как служба Windows. Вы можете увидеть его в Service Manager и в реестре по адресу:
3- Хорошо. Вы можете начать свою службу в сервис-менеджере.
Вы можете выполнить каждый файл python, который предоставляет этот сервисный скелет.
Источник: overcoder.net
Описание команды SC CREATE
Команда SC CREATE создает запись службы в реестре и в базе данных диспетчера служб. А для запуска только что созданной службы из командной строки служит команда SC START.
Синтаксис и параметры команды SC CREATE
sc [имя_сервера] create [имя_службы] [type= >] [start= ] [error= ] [binpath= имя_двоичного_пути] [group= группа_порядка_загрузки] [tag= ] [depend= зависимости] [obj= <имя_учетной_записи|имя_объекта>] [displayname= отображаемое_имя] [password= пароль]
- имя_сервера — Задает имя удаленного сервера, на котором находится служба. В имени следует использовать формат UNC («\myserver»). Чтобы запустить SC локально, этот параметр следует пропустить.
- имя_службы — Указывает имя службы, возвращенное операцией getkeyname.
- type= > — Указывает тип службы. Тип по умолчанию type= own.
- start= — Указывает тип запуска для службы. Тип запуска по умолчанию start= demand.
- error= — Указывает серьезность ошибки, если служба не запускается при загрузке. Значение параметра по умолчанию error= normal.
- binpath= имя_двоичного_пути — Указывает путь в двоичном файле службы. Значение по умолчанию для параметра binpath= не задано. Эту строку необходимо указать.
- group= группа_порядка_загрузки — Указывает имя группы, членом которой является эта служба. Список групп сохраняется в реестре в подразделе HKLMSystemCurrentControlSetControlServiceGroupOrder. Значение по умолчанию является пустым.
- tag= — Указывает, следует ли получить код TagID из вызова CreateService. Теги используются только драйверами, запускающимися при загрузке или запуске системы.
- depend= зависимости — Указывает имена служб и групп, которые должны быть запущены раньше данной службы. Имена разделяются косой чертой (/).
- obj= <имя_учетной_записи|имя_объекта>- Указывает имя учетной записи, для которой будет выполняться служба, или имя объекта драйвера Windows, в котором будет запущен драйвер
- displayname= отображаемое_имя — Определяет понятное, точное имя для службы, которое используется в программах пользовательского интерфейса.
- password= пароль — Задает пароль. Данный параметр требуется при использовании учетной записи, отличной от учетной записи «Локальная система».
- /? — Отображает справку в командной строке.
Примеры команды SC CREATE
- sc \myserver create NewService binpath= c:windowssystem32NewServ.exe
- sc create NewService binpath= c:windowssystem32NewServ.exe type= share start= auto depend= «+TDI Netbios»
Рекомендуем для просмотра:
- Запуск заданий в Windows по расписанию — 07/11/2012 08:52
- TASKKILL завершение процессов в Windows — 04/07/2010 14:24
- TASKLIST список процессов — 04/07/2010 14:14
Похожие темы:
- SC CONTINUE возобновление службы — 04/07/2010 14:04
- SC PAUSE пауза службы — 04/07/2010 14:01
- SC STOP остановка службы OC — 04/07/2010 13:57
Источник: cmd4win.ru
Создание простого systemd unit
Ранее на моем сайте уже выходила статья автозагрузка в Ubutnu. Там был рассмотрен метод автозагрузки с использованием файла rc.local. Но данный метод в современных дистрибутивах уже отключен, и считается устаревшим. Рассмотрим как пример создание простого systemd unit.
Что такое systemd?
systemd — это набор базовых строительных блоков для системы Linux. Он предоставляет диспетчер систем и служб, который работает как PID 1 и запускает остальную часть системы. systemd предоставляет агрессивные возможности распараллеливания, использует активацию сокетов и D-Bus для запуска служб.
Предлагает запуск демонов по требованию, отслеживает процессы, использующие группы управления Linux. Поддерживает точки монтирования и автоматического монтирования. Реализует сложную логику управления службами на основе транзакционных зависимостей. systemd поддерживает сценарии SysV и LSB init и работает как замена для sysvinit.
Другие части включают демон ведения журнала, утилиты для управления базовой конфигурацией системы. В него входит: имя хоста, дата, локаль, ведение списка зарегистрированных пользователей и запущенных контейнеров. А также виртуальных машин, системные учетные записи, каталоги времени выполнения и параметры. Не забудем о демонах управления простой конфигурацией сети, синхронизацией сетевого времени, пересылкой журналов и разрешением имен.
unitd работает с сервисами описанными в своей конфигурации. Основой для создания сервиса служит юнит (unit) — это текстовый файл с описанием на подобии ini файла в системе windows. Конфигурационный файл состоит из секций. Внутри каждой секции указываются необходимые параметры. Обязательными во всех юнитах являются две секции, остальные используются в зависимости от типа юнита.
Каталоги хранения юнитов
/usr/lib/systemd/system — юниты поставляемые вместе с системой и устанавливаемыми приложениями
/run/systemd/system — юниты созданные динамически (в рантайме)
/etc/systemd/system — юниты системного администратора (тут и будем хранить наши)
Юниты systemd
- target — группирует модули
- service — отвечает за запуск сервисов (служб) и поддерживает вызов интерпретаторов для исполнения пользовательских скриптов
- mount — занимается монтированием файловых систем
- automount — автомонтирование файловых систем, используется при обращении к точке монтирования;
- swap — отвечает за подключение файла подкачки
- timer — запускает модули по расписанию, аналог cron
- socket — запуск модуля при подключению к сокету
- slice — группировка других модулей в контейнер (дерево) cgroups
- device — использует реакцию на подключение какого-либо устройства
- path — запуск модуля по событию доступа по конкретному пути в файловой системе
Пример юнита sshd
[Unit] Description=OpenSSH server daemon Documentation=man:sshd(8) man:sshd_config(5) After=network.target sshd-keygen.target Wants=sshd-keygen.target [Service] Type=notify EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config EnvironmentFile=-/etc/sysconfig/sshd ExecStart=/usr/sbin/sshd -D $OPTIONS $CRYPTO_POLICY ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartSec=42s [Install] WantedBy=multi-user.target
Давайте рассмотрим данные секции подробнее. В секции [Unit] перечислена основная информация о юните и его зависимостях.
В секции [Service] указано какими командами нужно запускать, останавливать, перезапускать сервис. От какого пользователя он должен быть запущен и т.п. В секции [Install] указываем на каком уровне должен стартовать сервис (по аналогии с runlevel).
[Unit]
- Description — описание юнита для большего понимания
- Documentation — документация по процессу sshd
- After — зависимость, т.е. в данном случае запускать юнит только после запуска network.target и sshd-keygen.target
- Wants — еще одна зависимость, означает желательно. В примере Wants=sshd-keygen.target, т.е. желательно чтобы было запущено sshd-keygen.target . Желательно но не обязательно.
[Service]
Type — типы запуска служб. Могут быть
- simple (по умолчанию) — происходит незамедлительный запуск этой службы, с учетом того что процесс не разветвляется (fork). Не используйте simple если пользуетесь очередностью запуска. Одно исключение это активация сокета.
- forking — служба считается запущенной после того, после разветвления процесса с завершением родительского процесса. Используется для запуска классических демонов исключая случаи, когда в таком поведении процесса нет необходимости. Также желательно указать PIDFile=, чтобы systemd мог отслеживать основной процесс.
- oneshot — удобен для скриптов, которые выполняют одно задание и завершаются. При необходимости можно задать параметр RemainAfterExit=yes, чтобы systemd считал процесс активным даже после его завершения.
- notify — идентичен параметру simple, но с оговоркой, что демон пошлет systemd сигнал о своей готовности. Эталонная реализация данного уведомления представлена в libsystemd-daemon.so.
- dbus — служба считается находящейся в состоянии готовности, когда указанный параметр BusName появляется в системной шине DBus.
- idle — откладывается выполнение двоичного файла службы до момента выполнения всех остальных задач. В остальном поведение аналогично simple.
Далее в разделе Service
- EnvironmentFile — файлы переменного окружения
- ExecStart — полный путь к исполняемому файлу программы с параметрами запуска
- ExecReload — полный пусть к исполняемому файлу программы с параметрами перезапуска программы
- KillMode — указывается как будет завершен процесс. В данному случае параметр process говорит о том что будет закрыт только главный процесс
- Restart — перезагрузка процесса, параметр on-failure указывает на автоматическую перезагрузку в случает отказа процесса
- RestartSec — время ожидания через которое процесс должен перезагрузиться
[Install]
- WantedBy — указывает на каком урове запуска стартует сервис, параметр multi-user.target указывает на запуск в многопользовательском режиме без графики
Файлы с юнитами кладем в каталог /etc/systemd/system/
Итак начнем создание простого systemd unit, подопытным будет утилита мониторинга системы nmon. Откроем на редактирование файл юнита
sudo nano /etc/systemd/system/nmon.service
Добавим туда следующий код
[Unit] Description=NMON monitoring After=network.target [Service] Type=notify ExecStart=/usr/bin/nmon -V ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure [Install] WantedBy=multi-user.target
Добавить юнит в автозагрузку можно командой
systemctl enable nmon
Команда запуска юнита
systemctl start nmon
Статус можно посмотреть командой
systemctl status nmon
В данном случае процесс после запуска закрылся, потом как при старте был указан ключ -V. Он запустился вывел версию nmon и закрылся.
Важно помнить, если в системе работаем не под root, то перед каждой командой добавляем sudo. В данном случае я взял программу nmon просто для примера. Указанный ключ при запуске показывает номер версии nmon. SystemD имеет огромное количество настроек, в данной статье мы рассмотрели необходимый минимум для создания автозагрузки программы либо скрипта. Возможно в следующих статьях мы капнем systemd поглубже для изучения всех его интересных особенностей.
Для получения подробной информации по systemd, можно зайти на сайт разработчика.
Источник: newadmin.ru