Write ffmpeg dir to user PATH via registry instead of setx
setx truncates values at 1024 characters, and the old code fed it the merged process PATH (system + user), permanently duplicating every system entry into the user hive and silently dropping anything past the limit. Read and rewrite only the HKCU Environment Path value with winreg, preserving REG_EXPAND_SZ, and broadcast WM_SETTINGCHANGE. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user