-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall_windows_service.py
More file actions
189 lines (157 loc) · 5.83 KB
/
Copy pathinstall_windows_service.py
File metadata and controls
189 lines (157 loc) · 5.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#!/usr/bin/env python
"""
Instalador de servicio de Windows para ChronoBot
Requiere ejecutar como Administrador
"""
import sys
import os
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import time
from pathlib import Path
class ChronoBotService(win32serviceutil.ServiceFramework):
"""Servicio de Windows para ChronoBot"""
_svc_name_ = "ChronoBotService"
_svc_display_name_ = "ChronoBot - Automatización Bizneo"
_svc_description_ = "Servicio para automatizar el registro de entrada/salida en Bizneo"
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
self.running = True
# Obtener el directorio del script
if getattr(sys, 'frozen', False):
# Si está compilado como exe
self.app_path = os.path.dirname(sys.executable)
else:
# Si se ejecuta como script
self.app_path = os.path.dirname(os.path.abspath(__file__))
# Cambiar al directorio de la aplicación
os.chdir(self.app_path)
def SvcStop(self):
"""Detiene el servicio"""
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.stop_event)
self.running = False
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, '')
)
def SvcDoRun(self):
"""Ejecuta el servicio"""
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, '')
)
try:
self.main()
except Exception as e:
servicemanager.LogErrorMsg(f"Error en ChronoBot: {str(e)}")
def main(self):
"""Lógica principal del servicio"""
# Importar aquí para evitar problemas con paths
sys.path.insert(0, self.app_path)
from src.utils import Config, setup_logging, ensure_directories
from src.scheduler import ChronoScheduler
try:
# Configurar
ensure_directories()
config = Config()
logger = setup_logging(config)
logger.info("Servicio ChronoBot iniciado")
# Crear y ejecutar scheduler
scheduler = ChronoScheduler()
scheduler.setup_schedule()
# Loop principal
import schedule
while self.running:
schedule.run_pending()
# Esperar 30 segundos o hasta que se detenga el servicio
win32event.WaitForSingleObject(self.stop_event, 30000)
logger.info("Servicio ChronoBot detenido")
except Exception as e:
servicemanager.LogErrorMsg(f"Error en el servicio: {str(e)}")
raise
def install_service():
"""Instala el servicio"""
print("Instalando servicio ChronoBot...")
try:
win32serviceutil.InstallService(
ChronoBotService._svc_reg_class_,
ChronoBotService._svc_name_,
ChronoBotService._svc_display_name_,
startType=win32service.SERVICE_AUTO_START,
description=ChronoBotService._svc_description_
)
print("✅ Servicio instalado correctamente")
print(f" Nombre: {ChronoBotService._svc_display_name_}")
print(f" ID: {ChronoBotService._svc_name_}")
print()
print("Para iniciar el servicio:")
print(f" net start {ChronoBotService._svc_name_}")
print()
print("O usa el Administrador de Servicios de Windows (services.msc)")
except Exception as e:
print(f"❌ Error al instalar servicio: {e}")
print(" ¿Estás ejecutando como Administrador?")
sys.exit(1)
def uninstall_service():
"""Desinstala el servicio"""
print("Desinstalando servicio ChronoBot...")
try:
win32serviceutil.RemoveService(ChronoBotService._svc_name_)
print("✅ Servicio desinstalado correctamente")
except Exception as e:
print(f"❌ Error al desinstalar servicio: {e}")
sys.exit(1)
def start_service():
"""Inicia el servicio"""
print("Iniciando servicio ChronoBot...")
try:
win32serviceutil.StartService(ChronoBotService._svc_name_)
print("✅ Servicio iniciado correctamente")
except Exception as e:
print(f"❌ Error al iniciar servicio: {e}")
sys.exit(1)
def stop_service():
"""Detiene el servicio"""
print("Deteniendo servicio ChronoBot...")
try:
win32serviceutil.StopService(ChronoBotService._svc_name_)
print("✅ Servicio detenido correctamente")
except Exception as e:
print(f"❌ Error al detener servicio: {e}")
sys.exit(1)
def print_usage():
"""Imprime instrucciones de uso"""
print("Uso: python install_windows_service.py [comando]")
print()
print("Comandos disponibles:")
print(" install - Instala el servicio")
print(" uninstall - Desinstala el servicio")
print(" start - Inicia el servicio")
print(" stop - Detiene el servicio")
print()
print("NOTA: Debe ejecutarse como Administrador")
if __name__ == '__main__':
if len(sys.argv) < 2:
print_usage()
sys.exit(1)
command = sys.argv[1].lower()
if command == 'install':
install_service()
elif command == 'uninstall':
uninstall_service()
elif command == 'start':
start_service()
elif command == 'stop':
stop_service()
else:
print(f"❌ Comando desconocido: {command}")
print()
print_usage()
sys.exit(1)