""" 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)