diff --git a/ytsage/core/ytsage_ffmpeg.py b/ytsage/core/ytsage_ffmpeg.py index 6e7cf22..c2386b3 100644 --- a/ytsage/core/ytsage_ffmpeg.py +++ b/ytsage/core/ytsage_ffmpeg.py @@ -337,29 +337,35 @@ def install_ffmpeg_windows(progress_callback=None) -> bool: if progress_callback: progress_callback("🔧 Configuring system paths...") - # Add to System Path - user_path = os.environ.get("PATH", "") - path_parts = user_path.split(os.pathsep) - - # Remove old FFmpeg paths and add new one - cleaned_paths = [p for p in path_parts if "ffmpeg" not in p.lower() or str(bin_dir) in p] - if str(bin_dir) not in cleaned_paths: - cleaned_paths.insert(0, str(bin_dir)) - - new_path = os.pathsep.join(cleaned_paths) - + # Persist to the user PATH via the registry. setx must not be used here: + # it truncates values at 1024 characters, and os.environ["PATH"] is the + # merged system+user PATH, so writing it back would permanently duplicate + # every system entry into the user hive. try: - subprocess.run( - ["setx", "PATH", new_path], - creationflags=SUBPROCESS_CREATIONFLAGS, - timeout=30, - check=True, - ) - os.environ["PATH"] = new_path + import winreg + + with winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Environment", 0, winreg.KEY_READ | winreg.KEY_WRITE) as key: + try: + stored_path, value_type = winreg.QueryValueEx(key, "Path") + except FileNotFoundError: + stored_path, value_type = "", winreg.REG_EXPAND_SZ + user_parts = [p for p in stored_path.split(os.pathsep) if p] + # Drop stale ffmpeg entries we previously added, then prepend the new one + user_parts = [p for p in user_parts if "ffmpeg" not in p.lower() or p == str(bin_dir)] + if str(bin_dir) not in user_parts: + user_parts.insert(0, str(bin_dir)) + winreg.SetValueEx(key, "Path", 0, value_type, os.pathsep.join(user_parts)) + + # Broadcast the change so new shells pick it up without relogin + import ctypes + + ctypes.windll.user32.SendMessageTimeoutW(0xFFFF, 0x001A, 0, "Environment", 0x0002, 5000, None) except Exception as e: logger.warning(f"Failed to update PATH permanently: {e}") - # Still update for current session - os.environ["PATH"] = new_path + + # Update for the current session regardless + if str(bin_dir) not in os.environ.get("PATH", "").split(os.pathsep): + os.environ["PATH"] = str(bin_dir) + os.pathsep + os.environ.get("PATH", "") # Verify installation if progress_callback: