Skip to content

Commit dd1d2cd

Browse files
JaJaJaJa
authored andcommitted
fix: npx 擴充功能 Windows 路徑解析問題修復、自動確認安裝提示
1. npx 命令解析重構 - Extension.cs:新增 ResolveNpxCommand 方法,繞過 npx.cmd/npx shell 腳本直接用 node 執行 npx-cli.js - Extension.cs:新增 FindNpxCliPath 方法,在 PATH 中搜尋 node 安裝路徑並定位 npx-cli.js - Extension.cs:ResolveCommand 方法 npx 類型改為呼叫 ResolveNpxCommand 2. npx 執行優化 - Extension.cs:自動添加 --yes 參數,避免安裝確認提示導致非互動式執行卡住 - Extension.cs:統一所有平台(Windows/macOS/Linux)使用相同的 node npx-cli.js 策略 - Extension.cs:保留 fallback 機制,找不到 npx-cli.js 時仍使用原生 npx/npx.cmd
1 parent 592e010 commit dd1d2cd

File tree

1 file changed

+60
-2
lines changed

1 file changed

+60
-2
lines changed

Core/Extension/Extension.cs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,14 +1416,72 @@ private static CommandResolution ResolveCommand(ExtensionCommand command)
14161416
"python" => new CommandResolution(isWindows ? "python.exe" : "python3",
14171417
PrependExecutable(executable, argumentList)),
14181418
"dotnet" => new CommandResolution("dotnet", PrependExecutable(executable, argumentList)),
1419-
"npx" => new CommandResolution(isWindows ? "npx.cmd" : "npx",
1420-
PrependExecutable(executable, argumentList)),
1419+
"npx" => ResolveNpxCommand(executable, argumentList),
14211420
"pipx" => new CommandResolution(isWindows ? "pipx.exe" : "pipx",
14221421
PrependRun(executable, argumentList)),
14231422
_ => new CommandResolution(executable, argumentList)
14241423
};
14251424
}
14261425

1426+
/// <summary>
1427+
/// Resolves npx command by directly executing npx-cli.js with node to avoid
1428+
/// shell script path resolution issues when executed via Process.Start.
1429+
/// Adds --yes flag to auto-confirm package installation since extensions
1430+
/// run non-interactively and cannot respond to prompts.
1431+
/// </summary>
1432+
/// <param name="packageName">The npm package name to execute.</param>
1433+
/// <param name="arguments">Additional arguments for the package.</param>
1434+
/// <returns>A <see cref="CommandResolution" /> for npx execution.</returns>
1435+
private static CommandResolution ResolveNpxCommand(string packageName, List<string> arguments)
1436+
{
1437+
var npxArgs = new List<string>(arguments.Count + 2) { "--yes", packageName };
1438+
npxArgs.AddRange(arguments);
1439+
1440+
var isWindows = OperatingSystem.IsWindows();
1441+
var npxCliPath = FindNpxCliPath(isWindows);
1442+
1443+
if (npxCliPath != null)
1444+
{
1445+
var args = new List<string>(npxArgs.Count + 1) { npxCliPath };
1446+
args.AddRange(npxArgs);
1447+
return new CommandResolution(isWindows ? "node.exe" : "node", args);
1448+
}
1449+
1450+
return new CommandResolution(isWindows ? "npx.cmd" : "npx", npxArgs);
1451+
}
1452+
1453+
/// <summary>
1454+
/// Finds the path to npx-cli.js by searching PATH for node installation.
1455+
/// </summary>
1456+
/// <param name="isWindows">Whether the current platform is Windows.</param>
1457+
/// <returns>The full path to npx-cli.js, or null if not found.</returns>
1458+
private static string? FindNpxCliPath(bool isWindows)
1459+
{
1460+
var pathEnv = Environment.GetEnvironmentVariable("PATH");
1461+
if (string.IsNullOrEmpty(pathEnv))
1462+
return null;
1463+
1464+
var nodeExeName = isWindows ? "node.exe" : "node";
1465+
var paths = pathEnv.Split(Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries);
1466+
1467+
foreach (var path in paths)
1468+
try
1469+
{
1470+
var nodePath = Path.Combine(path, nodeExeName);
1471+
if (!File.Exists(nodePath))
1472+
continue;
1473+
1474+
var npxCliPath = Path.Combine(path, "node_modules", "npm", "bin", "npx-cli.js");
1475+
if (File.Exists(npxCliPath))
1476+
return npxCliPath;
1477+
}
1478+
catch
1479+
{
1480+
}
1481+
1482+
return null;
1483+
}
1484+
14271485
/// <summary>
14281486
/// Prepends the executable path to the argument list.
14291487
/// </summary>

0 commit comments

Comments
 (0)