From 5ca4d22cdfae913adffc461949ce4b60c1a69aef Mon Sep 17 00:00:00 2001 From: SamNet-dev Date: Wed, 4 Feb 2026 04:50:28 -0600 Subject: [PATCH] fix: GFK client Windows compatibility - replace pkill with taskkill - Replace Linux-only 'pkill' command with cross-platform solution - Use 'wmic' and 'taskkill' on Windows to kill existing Python processes - Add CREATE_NEW_PROCESS_GROUP for proper signal handling on Windows - Improve shutdown handling for both platforms Fixes FileNotFoundError: [WinError 2] when starting GFK on Windows. --- gfk/client/mainclient.py | 72 ++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 13 deletions(-) diff --git a/gfk/client/mainclient.py b/gfk/client/mainclient.py index efaee11..80fd3ee 100644 --- a/gfk/client/mainclient.py +++ b/gfk/client/mainclient.py @@ -3,36 +3,82 @@ import os import time import sys import signal +import platform +IS_WINDOWS = platform.system() == 'Windows' scripts = ['quic_client.py', 'vio_client.py'] +def kill_existing_script(script_name): + """Kill any existing instance of the script (cross-platform)""" + if IS_WINDOWS: + # On Windows, use taskkill to find and kill python processes + try: + result = subprocess.run( + ['wmic', 'process', 'where', + f"commandline like '%{script_name}%' and name like '%python%'", + 'get', 'processid'], + capture_output=True, text=True, stderr=subprocess.DEVNULL + ) + for line in result.stdout.split('\n'): + line = line.strip() + if line.isdigit(): + subprocess.run(['taskkill', '/F', '/PID', line], + stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL) + except Exception: + pass + else: + subprocess.run(['pkill', '-f', script_name], stderr=subprocess.DEVNULL) + + def run_script(script_name): - # Use sys.executable to run with the same Python interpreter (venv) - subprocess.run(['pkill', '-f', script_name], stderr=subprocess.DEVNULL) + """Start a script, killing any existing instance first""" + kill_existing_script(script_name) time.sleep(0.5) - p = subprocess.Popen([sys.executable, script_name]) + + if IS_WINDOWS: + p = subprocess.Popen([sys.executable, script_name], + creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) + else: + p = subprocess.Popen([sys.executable, script_name]) return p processes = [] -def signal_handler(sig, frame): - print('You pressed Ctrl+C!') - for p in processes: - print("terminated:",p) - p.terminate() + +def signal_handler(sig, frame): + print('\nShutting down GFK client...') + for p in processes: + try: + p.terminate() + p.wait(timeout=3) + except Exception: + try: + p.kill() + except Exception: + pass sys.exit(0) if __name__ == "__main__": + signal.signal(signal.SIGINT, signal_handler) + if not IS_WINDOWS: + signal.signal(signal.SIGTERM, signal_handler) + + print("Starting GFK client...") p1 = run_script(scripts[0]) time.sleep(1) p2 = run_script(scripts[1]) - processes.extend([p1, p2]) # Modify global list, don't shadow it - signal.signal(signal.SIGINT, signal_handler) - p1.wait() - p2.wait() - print("All subprocesses have completed.") + processes.extend([p1, p2]) + + print("GFK running. Press Ctrl+C to stop.\n") + + try: + p1.wait() + p2.wait() + print("All subprocesses have completed.") + except KeyboardInterrupt: + signal_handler(None, None)