fix: add shell=True for npm subprocess calls on Windows

On Windows, npm is installed as npm.cmd (a batch script), not a direct
executable. When subprocess.run() is called with a list like
['npm', 'install'] without shell=True, Python's CreateProcess cannot
locate npm.cmd, resulting in:

  FileNotFoundError: [WinError 2] The system cannot find the file specified

This fix adds a sys.platform == 'win32' check before each npm subprocess
call. On Windows, it uses shell=True with a string command so the shell
can resolve npm.cmd. On other platforms, the original list-based call is
preserved unchanged.

Affected locations:
- _get_bridge_dir(): npm install, npm run build
- channels_login(): npm start

No behavioral change on Linux/macOS.
This commit is contained in:
Peixian Gong
2026-03-03 19:56:05 +08:00
committed by Xubin Ren
parent af65145bc8
commit 805228e91e

View File

@@ -837,12 +837,19 @@ def _get_bridge_dir() -> Path:
shutil.copytree(source, user_bridge, ignore=shutil.ignore_patterns("node_modules", "dist"))
# Install and build
is_win = sys.platform == "win32"
try:
console.print(" Installing dependencies...")
subprocess.run(["npm", "install"], cwd=user_bridge, check=True, capture_output=True)
if is_win:
subprocess.run("npm install", cwd=user_bridge, check=True, capture_output=True, shell=True)
else:
subprocess.run(["npm", "install"], cwd=user_bridge, check=True, capture_output=True)
console.print(" Building...")
subprocess.run(["npm", "run", "build"], cwd=user_bridge, check=True, capture_output=True)
if is_win:
subprocess.run("npm run build", cwd=user_bridge, check=True, capture_output=True, shell=True)
else:
subprocess.run(["npm", "run", "build"], cwd=user_bridge, check=True, capture_output=True)
console.print("[green]✓[/green] Bridge ready\n")
except subprocess.CalledProcessError as e:
@@ -876,7 +883,10 @@ def channels_login():
env["AUTH_DIR"] = str(get_runtime_subdir("whatsapp-auth"))
try:
subprocess.run(["npm", "start"], cwd=bridge_dir, check=True, env=env)
if sys.platform == "win32":
subprocess.run("npm start", cwd=bridge_dir, check=True, env=env, shell=True)
else:
subprocess.run(["npm", "start"], cwd=bridge_dir, check=True, env=env)
except subprocess.CalledProcessError as e:
console.print(f"[red]Bridge failed: {e}[/red]")
except FileNotFoundError: