Как запустить скрипт Python как службу в Windows?
Я делаю набросок архитектуры для набора программ, которые совместно используют различные взаимосвязанные объекты, хранящиеся в базе данных. Я хочу, чтобы одна из программ действовала как служба, предоставляющая интерфейс более высокого уровня для операций с этими объектами, а другие программы - для доступа к объектам через эту службу.
В настоящее время я стремлюсь к Python и инфраструктуре Django в качестве технологий для реализации этого сервиса. Я уверен, что понимаю, как демонизировать программу Python в Linux. Однако это необязательный элемент спецификации, который система должна поддерживать Windows. У меня мало опыта в программировании Windows и совсем нет опыта работы со службами Windows.
Можно ли запускать программы Python как службу Windows (т.е. запускать ее автоматически без входа пользователя)? Мне не обязательно будет реализовывать эту часть, но мне нужно приблизительное представление о том, как это сделать, чтобы решить, следует ли проектировать в этом направлении.
Редактировать: Спасибо за все ответы, пока они достаточно полны. Я хотел бы знать еще одну вещь: как Windows знает о моем сервисе? Могу ли я управлять этим с помощью собственных утилит Windows? Что эквивалентно размещению сценария запуска / остановки в /etc/init.d?
15 ответов
Да, ты можешь. Я делаю это с использованием библиотек 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
метод
Простейшим способом является использование: NSSM - Менеджер неосасывающих услуг:
1 - сделать загрузку на https://nssm.cc/download
2 - установить программу на python как сервис: Win win от имени администратора
c:>nssm.exe установить WinService
3 - На консоли NSSM:
путь: C:\Python27\Python27.exe
Каталог запуска: C: \ Python27
Аргументы: c: \ WinService.py
4 - проверить созданные сервисы на services.msc
Хотя я проголосовал за выбранный ответ пару недель назад, тем временем я боролся с этой темой гораздо больше. Такое ощущение, что иметь специальную установку Python и использовать специальные модули для запуска скрипта как сервиса - просто неправильный путь. Как насчет портативности и тому подобное?
Я наткнулся на замечательного не сосущего Service Manager, который сделал его действительно простым и разумным для работы со службами Windows. Я подумал, что так как я мог передавать параметры установленной службе, я мог бы также выбрать свой исполняемый файл Python и передать свой сценарий в качестве опции.
Я еще не пробовал это решение, но я сделаю это прямо сейчас и обновлю этот пост по ходу процесса. Я также заинтересован в использовании virtualenvs в Windows, так что я могу рано или поздно придумать учебник и дать ссылку на него здесь.
Самый простой способ добиться этого - использовать встроенную команду sc.exe:
sc create PythonApp binPath= "C:\Python34\Python.exe --C:\tmp\pythonscript.py"
Существует пара альтернатив для установки в качестве службы практически любого исполняемого файла Windows.
Способ 1: использовать instsrv и 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 есть отличная удобная оболочка для этих утилит, которая называется " 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)? Как?
Пошаговое объяснение, как заставить это работать:
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, который предоставляет этот каркас службы.
nssm в Python 3+
(Я преобразовал свой файл.py в.exe с помощью pyinstaller)
nssm: как было сказано ранее
- запустите nssm install {ServiceName}
На консоли NSSM:
путь: путь \ к \ вашей \ программе.exe
Каталог запуска: путь \to\your\ # такой же, как путь, но без вашего program.exe
Аргументы: пусто
Если вы не хотите конвертировать свой проект в.exe
- создать файл.bat с
python {{your python.py file name}}
- и установите путь к файлу.bat
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
Я начал хостинг как сервис с pywin32.
Все было хорошо, но я столкнулся с проблемой, что служба не может запуститься в течение 30 секунд (время ожидания по умолчанию для Windows) при запуске системы. Это было очень важно для меня, потому что запуск Windows происходил одновременно на нескольких виртуальных машинах, размещенных на одной физической машине, и нагрузка ввода-вывода была огромной. Сообщения об ошибках были:
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, как было предложено в этом ответе. Было очень легко перейти на него.
Это не отвечает на первоначальный вопрос, но может помочь другим людям, которые хотят автоматически запускать скрипт Python при запуске Windows: вместо этого взгляните на планировщик заданий Windows , это намного проще, если вы просто хотите запустить скрипт после загрузки без всех сервисных функций службы Windows.
Создайте новую задачу, выберите «При запуске» в качестве триггера, «Запустить программу» в качестве действия с «C:\Python39\python.exe» в качестве программы (или где бы ни находился ваш python.exe) и полный путь к вашему скрипту ( "C:...\my_dir\xyz.py") в качестве аргумента (вы можете использовать ", если путь содержит пробелы). Вы также можете выбрать путь к вашему скрипту (без файла .py, например, "C:.. .\my_dir") для "начать с", если вы используете относительные пути в своем скрипте, например, для ведения журнала.
Этот ответ является плагиатором из нескольких источников на Stackru - большинство из них указано выше, но я забыл о других - извините. Это просто, и сценарии работают "как есть". Для выпусков вы тестируете сценарий, затем копируете его на сервер и останавливаете / запускаете соответствующую службу. И он должен работать для всех языков сценариев (Python, Perl, node.js), а также для пакетных сценариев, таких как GitBash, PowerShell, и даже для старых сценариев летучей мыши DOS. pyGlue - это связующее звено между службами Windows и вашим скриптом.
'''
A script to create a Windows Service, which, when started, will run an executable with the specified parameters.
Optionally, you can also specify a startup directory
To use this script you MUST define (in class Service)
1. A name for your service (short - preferably no spaces)
2. A display name for your service (the name visibile in Windows Services)
3. A description for your service (long details visible when you inspect the service in Windows Services)
4. The full path of the executable (usually C:/Python38/python.exe or C:WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe
5. The script which Python or PowerShell will run(or specify None if your executable is standalone - in which case you don't need pyGlue)
6. The startup directory (or specify None)
7. Any parameters for your script (or for your executable if you have no script)
NOTE: This does not make a portable script.
The associated '_svc_name.exe' in the dist folder will only work if the executable,
(and any optional startup directory) actually exist in those locations on the target system
Usage: 'pyGlue.exe [options] install|update|remove|start [...]|stop|restart [...]|debug [...]'
Options for 'install' and 'update' commands only:
--username domain\\username : The Username the service is to run under
--password password : The password for the username
--startup [manual|auto|disabled|delayed] : How the service starts, default = manual
--interactive : Allow the service to interact with the desktop.
--perfmonini file: .ini file to use for registering performance monitor data
--perfmondll file: .dll file to use when querying the service for performance data, default = perfmondata.dll
Options for 'start' and 'stop' commands only:
--wait seconds: Wait for the service to actually start or stop.
If you specify --wait with the 'stop' option, the service and all dependent services will be stopped,
each waiting the specified period.
'''
# Import all the modules that make life easy
import servicemanager
import socket
import sys
import win32event
import win32service
import win32serviceutil
import win32evtlogutil
import os
from logging import Formatter, Handler
import logging
import subprocess
# Define the win32api class
class Service (win32serviceutil.ServiceFramework):
# The following variable are edited by the build.sh script
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
_svc_description_ = "Test Running Python Scripts as a Service"
service_exe = 'c:/Python27/python.exe'
service_script = None
service_params = []
service_startDir = None
# Initialize the service
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
self.configure_logging()
socket.setdefaulttimeout(60)
# Configure logging to the WINDOWS Event logs
def configure_logging(self):
self.formatter = Formatter('%(message)s')
self.handler = logHandler()
self.handler.setFormatter(self.formatter)
self.logger = logging.getLogger()
self.logger.addHandler(self.handler)
self.logger.setLevel(logging.INFO)
# Stop the service
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
# Run the service
def SvcDoRun(self):
self.main()
# This is the service
def main(self):
# Log that we are starting
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
# Fire off the real process that does the real work
logging.info('%s - about to call Popen() to run %s %s %s', self._svc_name_, self.service_exe, self.service_script, self.service_params)
self.process = subprocess.Popen([self.service_exe, self.service_script] + self.service_params, shell=False, cwd=self.service_startDir)
logging.info('%s - started process %d', self._svc_name_, self.process.pid)
# Wait until WINDOWS kills us - retrigger the wait for stop every 60 seconds
rc = None
while rc != win32event.WAIT_OBJECT_0:
rc = win32event.WaitForSingleObject(self.hWaitStop, (1 * 60 * 1000))
# Shut down the real process and exit
logging.info('%s - is terminating process %d', self._svc_name_, self.process.pid)
self.process.terminate()
logging.info('%s - is exiting', self._svc_name_)
class logHandler(Handler):
'''
Emit a log record to the WINDOWS Event log
'''
def emit(self, record):
servicemanager.LogInfoMsg(record.getMessage())
# The main code
if __name__ == '__main__':
'''
Create a Windows Service, which, when started, will run an executable with the specified parameters.
'''
# Check that configuration contains valid values just in case this service has accidentally
# been moved to a server where things are in different places
if not os.path.isfile(Service.service_exe):
print('Executable file({!s}) does not exist'.format(Service.service_exe), file=sys.stderr)
sys.exit(0)
if not os.access(Service.service_exe, os.X_OK):
print('Executable file({!s}) is not executable'.format(Service.service_exe), file=sys.stderr)
sys.exit(0)
# Check that any optional startup directory exists
if (Service.service_startDir is not None) and (not os.path.isdir(Service.service_startDir)):
print('Start up directory({!s}) does not exist'.format(Service.service_startDir), file=sys.stderr)
sys.exit(0)
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(Service)
servicemanager.StartServiceCtrlDispatcher()
else:
# install/update/remove/start/stop/restart or debug the service
# One of those command line options must be specified
win32serviceutil.HandleCommandLine(Service)
Теперь нужно немного отредактировать, и вы не хотите, чтобы все ваши сервисы назывались pyGlue. Итак, есть сценарий (build.sh) для вставки битов и создания настраиваемого "pyGlue" и создания ".exe". Это файл.exe, который устанавливается как служба Windows. После установки вы можете настроить его на автоматический запуск.
#!/bin/sh
# This script build a Windows Service that will install/start/stop/remove a service that runs a script
# That is, executes Python to run a Python script, or PowerShell to run a PowerShell script, etc
if [ $# -lt 6 ]; then
echo "Usage: build.sh Name Display Description Executable Script StartupDir [Params]..."
exit 0
fi
name=$1
display=$2
desc=$3
exe=$4
script=$5
startDir=$6
shift; shift; shift; shift; shift; shift
params=
while [ $# -gt 0 ]; do
if [ "${params}" != "" ]; then
params="${params}, "
fi
params="${params}'$1'"
shift
done
cat pyGlue.py | sed -e "s/pyGlue/${name}/g" | \
sed -e "/_svc_name_ =/s?=.*?= '${name}'?" | \
sed -e "/_svc_display_name_ =/s?=.*?= '${display}'?" | \
sed -e "/_svc_description_ =/s?=.*?= '${desc}'?" | \
sed -e "/service_exe =/s?=.*?= '$exe'?" | \
sed -e "/service_script =/s?=.*?= '$script'?" | \
sed -e "/service_params =/s?=.*?= [${params}]?" | \
sed -e "/service_startDir =/s?=.*?= '${startDir}'?" > ${name}.py
cxfreeze ${name}.py --include-modules=win32timezone
Установка - скопируйте '.exe' сервер и скрипт в указанную папку. Запустите.exe от имени администратора с опцией "установить". Откройте службы Windows в качестве администратора и запустите службу. Для обновления просто скопируйте новую версию скрипта и остановите / запустите службу.
Теперь все серверы разные - разные установки Python, разные структуры папок. Я поддерживаю папку для каждого сервера с копией pyGlue.py и build.sh. И я создаю сценарий serverBuild.sh для восстановления всей службы на этом сервере.
# A script to build all the script based Services on this PC
sh build.sh AutoCode 'AutoCode Medical Documents' 'Autocode Medical Documents to SNOMED_CT and AIHW codes' C:/Python38/python.exe autocode.py C:/Users/russell/Documents/autocoding -S -T
Полный пример pywin32 с использованием цикла или подпотока
Поработав над этим в течение нескольких дней, вот ответ, который я хотел бы найти, используя pywin32, чтобы он оставался красивым и самодостаточным.
Это полный рабочий код для решения на основе одного цикла и одного потока. Он может работать как на python 2, так и на 3, хотя я тестировал только последнюю версию на 2.7 и Win7. Цикл должен подходить для опроса кода, а протектор должен работать с кодом, более похожим на сервер. Кажется, он прекрасно работает с wsgi-сервером официантки, у которого нет стандартного способа корректного завершения работы.
Я также хотел бы отметить, что, похоже, существует множество примеров, подобных этому, которые почти полезны, но на самом деле вводят в заблуждение, потому что они слепо вырезали и вставляли другие примеры. Я могу ошибаться. но зачем создавать событие, если вы его никогда не ждете?
Тем не менее, я все еще чувствую, что я здесь несколько шатко, особенно в отношении того, насколько чистым является выход из версии потока, но, по крайней мере, я считаю, что здесь нет ничего вводящего в заблуждение.
Для запуска просто скопируйте код в файл и следуйте инструкциям.
Обновить:
Используйте простой флаг для завершения потока. Важным моментом является то, что печать "нить сделана".
Более подробный пример выхода из потока неконтролируемого сервера см. В моем сообщении о wsgi-сервере официантки.
# uncomment mainthread() or mainloop() call below
# run without parameters to see HandleCommandLine options
# install service with "install" and remove with "remove"
# run with "debug" to see print statements
# with "start" and "stop" watch for files to appear
# check Windows EventViever for log messages
import socket
import sys
import threading
import time
from random import randint
from os import path
import servicemanager
import win32event
import win32service
import win32serviceutil
# see http://timgolden.me.uk/pywin32-docs/contents.html for details
def dummytask_once(msg='once'):
fn = path.join(path.dirname(__file__),
'%s_%s.txt' % (msg, randint(1, 10000)))
with open(fn, 'w') as fh:
print(fn)
fh.write('')
def dummytask_loop():
global do_run
while do_run:
dummytask_once(msg='loop')
time.sleep(3)
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global do_run
do_run = True
print('thread start\n')
dummytask_loop()
print('thread done\n')
def exit(self):
global do_run
do_run = False
class SMWinservice(win32serviceutil.ServiceFramework):
_svc_name_ = 'PyWinSvc'
_svc_display_name_ = 'Python Windows Service'
_svc_description_ = 'An example of a windows service in Python'
@classmethod
def parse_command_line(cls):
win32serviceutil.HandleCommandLine(cls)
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.stopEvt = win32event.CreateEvent(None, 0, 0, None) # create generic event
socket.setdefaulttimeout(60)
def SvcStop(self):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, ''))
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.stopEvt) # raise event
def SvcDoRun(self):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
# UNCOMMENT ONE OF THESE
# self.mainthread()
# self.mainloop()
# Wait for stopEvt indefinitely after starting thread.
def mainthread(self):
print('main start')
self.server = MyThread()
self.server.start()
print('wait for win32event')
win32event.WaitForSingleObject(self.stopEvt, win32event.INFINITE)
self.server.exit()
print('wait for thread')
self.server.join()
print('main done')
# Wait for stopEvt event in loop.
def mainloop(self):
print('loop start')
rc = None
while rc != win32event.WAIT_OBJECT_0:
dummytask_once()
rc = win32event.WaitForSingleObject(self.stopEvt, 3000)
print('loop done')
if __name__ == '__main__':
SMWinservice.parse_command_line()
Принятый ответ с использованием win32serviceutil
работает, но сложно и усложняет отладку и изменения. Намного проще использовать NSSM ( диспетчер неосасывающих услуг). Вы пишете и удобно отлаживаете обычную программу на Python, и когда она наконец работает, вы используете NSSM, чтобы установить ее как службу менее чем за минуту:
Из командной строки с повышенными правами (admin) вы запускаете nssm.exe install NameOfYourService
и вы заполняете эти параметры:
- путь: (путь к python.exe, например
C:\Python27\Python.exe
) - Аргументы: (путь к вашему скрипту Python, например
c:\path\to\program.py
)
Кстати, если ваша программа печатает полезные сообщения, которые вы хотите сохранить в файле журнала, NSSM также может обработать это и многое другое для вас.
Для тех, кто хочет создать сервис в VENV или Pycharm!!!!!!!
После прочтения всех ответов и создания некоторых скриптов, если вы можете запустить python service.py install
а также python service.py debug
, но python service.py start
не имеет ответа.
Может быть, это вызвано проблемой venv, потому что служба Windows запускает вашу службу exec PROJECT\venv\Lib\site-packages\win32\pythonservice.exe
,
Ты можешь использовать powershell
или же cmd
проверить ваш сервис, чтобы найти больше деталей об ошибке.
PS C:\Users\oraant> E:
PS E:\> cd \Software\PythonService\venv\Lib\site-packages\win32
PS E:\Software\PythonService\venv\Lib\site-packages\win32> .\pythonservice.exe -debug ttttt
Debugging service ttttt - press Ctrl+C to stop.
Error 0xC0000004 - Python could not import the service's module
Traceback (most recent call last):
File "E:\Software\PythonService\my_service.py", line 2, in <module>
import win32serviceutil
ModuleNotFoundError: No module named 'win32serviceutil'
(null): (null)
Если вы получаете какую-то ошибку, как я, вы можете проверить мой ответ в другом вопросе, я исправил его и опубликовал свой код здесь.
https://www.chrisumbel.com/article/windows_services_in_python
Следите за PySvc.py
изменение папки dll
Я знаю, что это старое, но я застрял на этом навсегда. Для меня эта конкретная проблема была решена путем копирования этого файла - pywintypes36.dll
Из -> Python36\Lib\site-packages\pywin32_system32
Кому -> Python36\Lib\site-packages\win32
setx /M PATH "%PATH%;C:\Users\user\AppData\Local\Programs\Python\Python38-32;C:\Users\user\AppData\Local\Programs\Python\Python38-32\Scripts;C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\pywin32_system32;C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\win32
- изменение пути к папке python на
cd C:\Users\user\AppData\Local\Programs\Python\Python38-32
NET START PySvc
NET STOP PySvc