143 lines
4.9 KiB
Python
143 lines
4.9 KiB
Python
"""
|
|
Windows Service Installation and Management
|
|
==========================================
|
|
|
|
This module handles Windows service installation, configuration, and management
|
|
for the Quality Recticel Print Service.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
import win32serviceutil
|
|
import win32service
|
|
import win32event
|
|
import servicemanager
|
|
import socket
|
|
from pathlib import Path
|
|
|
|
class QualityRecticelPrintService(win32serviceutil.ServiceFramework):
|
|
"""Windows Service wrapper for the print service"""
|
|
|
|
_svc_name_ = "QualityRecticelPrintService"
|
|
_svc_display_name_ = "Quality Recticel Print Service"
|
|
_svc_description_ = "Local API service for silent PDF printing via Chrome extension"
|
|
|
|
def __init__(self, args):
|
|
win32serviceutil.ServiceFramework.__init__(self, args)
|
|
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
|
|
self.is_alive = True
|
|
|
|
def SvcStop(self):
|
|
"""Stop the service"""
|
|
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
|
|
win32event.SetEvent(self.hWaitStop)
|
|
self.is_alive = False
|
|
servicemanager.LogMsg(
|
|
servicemanager.EVENTLOG_INFORMATION_TYPE,
|
|
servicemanager.PYS_SERVICE_STOPPED,
|
|
(self._svc_name_, '')
|
|
)
|
|
|
|
def SvcDoRun(self):
|
|
"""Run the service"""
|
|
servicemanager.LogMsg(
|
|
servicemanager.EVENTLOG_INFORMATION_TYPE,
|
|
servicemanager.PYS_SERVICE_STARTED,
|
|
(self._svc_name_, '')
|
|
)
|
|
|
|
# Import and run the print service
|
|
try:
|
|
from print_service import WindowsPrintService
|
|
|
|
service = WindowsPrintService(port=8765)
|
|
|
|
# Run service in a separate thread
|
|
import threading
|
|
service_thread = threading.Thread(target=service.run_service)
|
|
service_thread.daemon = True
|
|
service_thread.start()
|
|
|
|
# Wait for stop event
|
|
win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)
|
|
|
|
except Exception as e:
|
|
servicemanager.LogErrorMsg(f"Service error: {e}")
|
|
|
|
def install_service():
|
|
"""Install the Windows service"""
|
|
try:
|
|
# Install the service with automatic startup
|
|
win32serviceutil.InstallService(
|
|
QualityRecticelPrintService._svc_reg_class_,
|
|
QualityRecticelPrintService._svc_name_,
|
|
QualityRecticelPrintService._svc_display_name_,
|
|
description=QualityRecticelPrintService._svc_description_,
|
|
startType=win32service.SERVICE_AUTO_START # Auto-start on system boot
|
|
)
|
|
|
|
print(f"✅ Service '{QualityRecticelPrintService._svc_display_name_}' installed successfully")
|
|
print(f"🔄 Service configured for AUTOMATIC startup on system restart")
|
|
|
|
# Start the service
|
|
win32serviceutil.StartService(QualityRecticelPrintService._svc_name_)
|
|
print(f"✅ Service started successfully")
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Service installation failed: {e}")
|
|
return False
|
|
|
|
def uninstall_service():
|
|
"""Uninstall the Windows service"""
|
|
try:
|
|
# Stop the service first
|
|
try:
|
|
win32serviceutil.StopService(QualityRecticelPrintService._svc_name_)
|
|
print(f"✅ Service stopped")
|
|
except:
|
|
pass # Service might not be running
|
|
|
|
# Remove the service
|
|
win32serviceutil.RemoveService(QualityRecticelPrintService._svc_name_)
|
|
print(f"✅ Service '{QualityRecticelPrintService._svc_display_name_}' uninstalled successfully")
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Service uninstallation failed: {e}")
|
|
return False
|
|
|
|
def service_status():
|
|
"""Get service status"""
|
|
try:
|
|
status = win32serviceutil.QueryServiceStatus(QualityRecticelPrintService._svc_name_)
|
|
|
|
status_names = {
|
|
win32service.SERVICE_STOPPED: "Stopped",
|
|
win32service.SERVICE_START_PENDING: "Start Pending",
|
|
win32service.SERVICE_STOP_PENDING: "Stop Pending",
|
|
win32service.SERVICE_RUNNING: "Running",
|
|
win32service.SERVICE_CONTINUE_PENDING: "Continue Pending",
|
|
win32service.SERVICE_PAUSE_PENDING: "Pause Pending",
|
|
win32service.SERVICE_PAUSED: "Paused"
|
|
}
|
|
|
|
current_status = status_names.get(status[1], "Unknown")
|
|
print(f"Service Status: {current_status}")
|
|
|
|
return status[1]
|
|
|
|
except Exception as e:
|
|
print(f"❌ Failed to get service status: {e}")
|
|
return None
|
|
|
|
if __name__ == '__main__':
|
|
if len(sys.argv) == 1:
|
|
servicemanager.Initialize()
|
|
servicemanager.PrepareToHostSingle(QualityRecticelPrintService)
|
|
servicemanager.StartServiceCtrlDispatcher()
|
|
else:
|
|
win32serviceutil.HandleCommandLine(QualityRecticelPrintService) |