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

Системный администратор IT и автоматизация бизнеса
← На главную

Часто при разработке инструментов автоматизации, таких как Telegram-боты на Python, возникает необходимость обеспечить их круглосуточную работу. Обычный запуск через консоль неудобен тем, что программа закрывается при выходе пользователя из системы. Использование планировщика задач Windows не всегда спасает, особенно при «холодном старте» (включении питания), когда механизмы быстрого запуска Windows могут игнорировать стандартные триггеры. Разберем подробно, как превратить ваш Python-скрипт в полноценную системную службу, которая будет стартовать вместе с операционной системой.

Проблема холодного запуска и планировщика задач

Проанализируем ситуацию, когда скрипт, прописанный в планировщике, работает при перезагрузке, но игнорируется при включении компьютера. Выясним причину: в современных версиях Windows (10 и 11) по умолчанию активна функция Fast Startup (Быстрый запуск). При выключении компьютера система не завершает работу полностью, а сохраняет состояние ядра в файл гибернации. В результате при включении триггер «При запуске системы» может не сработать. Для решения этой проблемы рассмотрим использование полноценных служб (Services), которые управляются диспетчером Service Control Manager (SCM).

Метод 1: Создание службы через PowerShell

Самый простой способ, предложенный участниками обсуждения, — использование встроенной команды PowerShell New-Service. Это позволяет зарегистрировать любой исполняемый файл (EXE), полученный после компиляции Python-скрипта (например, через PyInstaller), в реестре служб. Рассмотрим этот процесс по шагам.

Запустим оболочку PowerShell от имени администратора и воспользуемся следующей конструкцией:


New-Service -Name "MyTelegramBot" `
            -BinaryPathName "C:\Path\To\Your\bot.exe" `
            -DisplayName "Telegram Bot Service" `
            -StartupType Automatic

Однако здесь есть важный технический нюанс. Если ваша программа — это обычное консольное приложение, Windows может выдать ошибку 1053 («Служба не ответила на запрос своевременно»). Это происходит потому, что обычный EXE не умеет отправлять сигнал «я запустился» диспетчеру служб Windows. Посмотрим, как обойти это ограничение в следующих разделах.

Метод 2: Использование утилиты-обертки (NSSM)

Если ваш скрипт не содержит специфического кода для взаимодействия с SCM, мы рекомендуем использовать «обертку». Самым надежным инструментом является NSSM (Non-Sucking Service Manager). Проанализируем, почему это лучший выбор для Python-разработчика: NSSM берет на себя все общение с Windows, а ваш скрипт просто работает внутри нее как дочерний процесс. Если бот упадет из-за ошибки сети, NSSM автоматически его перезапустит.

Разберем алгоритм настройки через NSSM:

  1. Скачаем утилиту и через командную строку (cmd) запустим установку: nssm install MyBotService.
  2. В появившемся окне укажем путь к python.exe или вашему скомпилированному bot.exe.
  3. В поле Startup directory обязательно укажем рабочую папку скрипта, чтобы он не потерял пути к файлам конфигурации или базам данных.
  4. На вкладке Details установим тип запуска "Automatic".
  5. На вкладке Log on выберем "Local System account" и разрешим взаимодействие с рабочим столом, если это необходимо (хотя для бота это лишнее).

Метод 3: Настройка планировщика для работы «до входа пользователя»

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

При использовании этого метода важно помнить, что программа будет запущена в так называемой Сессии 0. Это означает отсутствие графического интерфейса. Все пути в коде должны быть абсолютными.

Метод 4: Реализация службы средствами Python (библиотека pywin32)

Для тех, кто предпочитает «чистое» решение без сторонних утилит, рассмотрим использование библиотеки pywin32. Это позволит скрипту корректно обрабатывать команды системы: Stop, Pause и Shutdown. Проанализируем пример кода для создания правильной службы:


import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import sys

class MyBotService(win32serviceutil.ServiceFramework):
    _svc_name_ = "PyBotService"
    _svc_display_name_ = "Python Telegram Bot Service"

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
        self.stop_requested = False

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

    def SvcDoRun(self):
        # Здесь инициализируем запуск вашего бота
        main_loop_of_your_bot()

В методе SvcDoRun мы запускаем основной цикл бота, а в SvcStop корректно завершаем его работу. Это предотвращает принудительное «убийство» процесса системой при выключении ПК.

Важные рекомендации по окружению и путям

Разберем типичные ошибки, из-за которых службы не стартуют:

  1. Рабочая директория: При запуске службы текущей директорией часто становится C:\Windows\System32. Всегда используйте os.path.abspath для определения путей к конфигам.
  2. Ожидание сети: Службы стартуют очень быстро, иногда до того, как инициализируется сетевой стек или Wi-Fi. Добавим в начало скрипта проверку доступности интернета (например, попытку пинга серверов Telegram в цикле).
  3. Логирование: Поскольку консоли в Сессии 0 нет, все ошибки print() уйдут в никуда. Обязательно настройте библиотеку logging для записи событий в файл.

Подведем итог: для быстрого и надежного результата мы рекомендуем использовать утилиту NSSM. Если же вы стремитесь к максимальной интеграции с Windows и хотите избежать сторонних зависимостей, используйте pywin32. Главное — убедиться, что служба запускается от имени учетной записи с достаточными правами доступа к сетевым ресурсам и файловой системе.

← На главную