#!/usr/bin/env python3 """ Windows Service Wrapper - Handles Windows Service Communication Fixes Error 1053 by properly communicating with Service Control Manager """ import sys import os import time import logging import subprocess import threading import signal from pathlib import Path # Simple service state management class WindowsServiceManager: def __init__(self): self.service_process = None self.should_stop = False self.service_thread = None def setup_logging(self): """Setup service logging.""" log_dir = os.path.join(os.path.expanduser("~"), "PrintService", "logs") os.makedirs(log_dir, exist_ok=True) log_file = os.path.join(log_dir, f"service_wrapper_{time.strftime('%Y%m%d')}.log") logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler(log_file, encoding='utf-8'), logging.StreamHandler(sys.stdout) ] ) def signal_handler(self, signum, frame): """Handle shutdown signals.""" logging.info(f"Service wrapper received signal {signum}") self.stop_service() def start_service(self): """Start the actual print service.""" script_dir = Path(__file__).parent service_script = script_dir / "print_service_complete.py" if not service_script.exists(): logging.error(f"Service script not found: {service_script}") return False try: # Get Python executable path python_exe = sys.executable if not python_exe: python_exe = "python" logging.info(f"Starting print service with: {python_exe} {service_script}") # Start the service process self.service_process = subprocess.Popen( [python_exe, str(service_script), "--service"], cwd=str(script_dir), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1, universal_newlines=True ) # Monitor service output def monitor_output(): if self.service_process: for line in iter(self.service_process.stdout.readline, ''): if line: logging.info(f"Service: {line.strip()}") if self.should_stop: break self.service_thread = threading.Thread(target=monitor_output, daemon=True) self.service_thread.start() logging.info("Print service started successfully") return True except Exception as e: logging.error(f"Failed to start service: {e}") return False def stop_service(self): """Stop the print service.""" logging.info("Stopping print service...") self.should_stop = True if self.service_process: try: # Try graceful shutdown first self.service_process.terminate() # Wait up to 10 seconds for graceful shutdown for _ in range(10): if self.service_process.poll() is not None: break time.sleep(1) # Force kill if still running if self.service_process.poll() is None: logging.warning("Force killing service process") self.service_process.kill() self.service_process.wait() logging.info("Print service stopped") except Exception as e: logging.error(f"Error stopping service: {e}") def run_service(self): """Main service loop.""" logging.info("Windows Print Service Wrapper starting...") # Setup signal handlers signal.signal(signal.SIGTERM, self.signal_handler) signal.signal(signal.SIGINT, self.signal_handler) if hasattr(signal, 'SIGBREAK'): signal.signal(signal.SIGBREAK, self.signal_handler) # Start the actual service if not self.start_service(): logging.error("Failed to start print service") return 1 # Service main loop - keep running until stopped try: while not self.should_stop: # Check if service process is still running if self.service_process and self.service_process.poll() is not None: logging.warning("Service process died, restarting...") if not self.start_service(): logging.error("Failed to restart service") break time.sleep(5) # Check every 5 seconds except KeyboardInterrupt: logging.info("Service interrupted by user") except Exception as e: logging.error(f"Service loop error: {e}") finally: self.stop_service() logging.info("Windows Print Service Wrapper stopped") return 0 def main(): """Main entry point.""" service_manager = WindowsServiceManager() service_manager.setup_logging() # Check command line arguments if len(sys.argv) > 1: if sys.argv[1] == "install": logging.info("Service install requested - use install_service_complete.bat instead") return 1 elif sys.argv[1] == "start": logging.info("Service start requested") elif sys.argv[1] == "stop": logging.info("Service stop requested") return 0 # Run the service return service_manager.run_service() if __name__ == "__main__": sys.exit(main())