fix: 修复用户级安装的 Chrome 探测失败
- LOCALAPPDATA 环境变量缺失(受限启动环境)时退回 os.homedir() 拼接 AppData/Local 候选路径 - 注册表 App Paths 兜底从仅 HKLM 扩展为 HKLM + WOW6432Node + HKCU(用户级安装的 Chrome 注册在 HKCU) - 本机复现: Chrome 装于 C:/Users/6/AppData/Local, 注册于 HKCU App Paths, 修复后可探测到
这个提交包含在:
1 父节点
f28b5ffc5e
当前提交
fd507e4f62
1 个文件已更改
+30
-13
+30
-13
@@ -52,7 +52,7 @@ const BROWSER_CANDIDATE_PATHS: Record<ExternalBrowserType, string[]> = {
|
|||||||
chrome: [
|
chrome: [
|
||||||
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
|
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
|
||||||
"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
|
"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
|
||||||
path.join(process.env.LOCALAPPDATA ?? "", "Google", "Chrome", "Application", "chrome.exe")
|
path.join(localAppDataDir(), "Google", "Chrome", "Application", "chrome.exe")
|
||||||
],
|
],
|
||||||
edge: [
|
edge: [
|
||||||
"C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",
|
"C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",
|
||||||
@@ -60,9 +60,24 @@ const BROWSER_CANDIDATE_PATHS: Record<ExternalBrowserType, string[]> = {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
const BROWSER_APP_PATHS_REGISTRY: Record<ExternalBrowserType, string> = {
|
/** 用户级 AppData\Local 目录;LOCALAPPDATA 缺失(如受限启动环境)时退回 USERPROFILE 拼接 */
|
||||||
chrome: "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe",
|
function localAppDataDir(): string {
|
||||||
edge: "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\msedge.exe"
|
if (process.env.LOCALAPPDATA) return process.env.LOCALAPPDATA;
|
||||||
|
return path.join(os.homedir(), "AppData", "Local");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 注册表 App Paths 兜底:HKLM(64 位 + WOW6432Node)与 HKCU(用户级安装)都查 */
|
||||||
|
const BROWSER_APP_PATHS_REGISTRIES: Record<ExternalBrowserType, string[]> = {
|
||||||
|
chrome: [
|
||||||
|
"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe",
|
||||||
|
"HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe",
|
||||||
|
"HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe"
|
||||||
|
],
|
||||||
|
edge: [
|
||||||
|
"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\msedge.exe",
|
||||||
|
"HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\App Paths\\msedge.exe",
|
||||||
|
"HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\msedge.exe"
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
async function fileExists(p: string): Promise<boolean> {
|
async function fileExists(p: string): Promise<boolean> {
|
||||||
@@ -84,20 +99,22 @@ function queryRegistry(command: string): Promise<string> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 探测本机浏览器安装路径:常见目录优先,注册表 App Paths 兜底 */
|
/** 探测本机浏览器安装路径:常见目录优先,注册表 App Paths(HKLM/HKCU)兜底 */
|
||||||
export async function detectBrowserPath(browserType: ExternalBrowserType): Promise<string> {
|
export async function detectBrowserPath(browserType: ExternalBrowserType): Promise<string> {
|
||||||
for (const candidate of BROWSER_CANDIDATE_PATHS[browserType]) {
|
for (const candidate of BROWSER_CANDIDATE_PATHS[browserType]) {
|
||||||
if (await fileExists(candidate)) return candidate;
|
if (await fileExists(candidate)) return candidate;
|
||||||
}
|
}
|
||||||
try {
|
for (const registryKey of BROWSER_APP_PATHS_REGISTRIES[browserType]) {
|
||||||
const stdout = await queryRegistry(BROWSER_APP_PATHS_REGISTRY[browserType]);
|
try {
|
||||||
const match = stdout.match(/REG_SZ\s+(\S[^\r\n]*)/);
|
const stdout = await queryRegistry(registryKey);
|
||||||
if (match) {
|
const match = stdout.match(/REG_SZ\s+(\S[^\r\n]*)/);
|
||||||
const registryPath = match[1].trim();
|
if (match) {
|
||||||
if (await fileExists(registryPath)) return registryPath;
|
const registryPath = match[1].trim();
|
||||||
|
if (await fileExists(registryPath)) return registryPath;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// 该键不存在继续查下一个
|
||||||
}
|
}
|
||||||
} catch {
|
|
||||||
// 注册表查询失败继续走报错
|
|
||||||
}
|
}
|
||||||
throw new RuntimeError(
|
throw new RuntimeError(
|
||||||
"browser_not_found",
|
"browser_not_found",
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户