diff --git a/src/main/browser/external.ts b/src/main/browser/external.ts index 76b1c97..8d93f1a 100644 --- a/src/main/browser/external.ts +++ b/src/main/browser/external.ts @@ -52,7 +52,7 @@ const BROWSER_CANDIDATE_PATHS: Record = { chrome: [ "C:\\Program Files\\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: [ "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe", @@ -60,9 +60,24 @@ const BROWSER_CANDIDATE_PATHS: Record = { ] }; -const BROWSER_APP_PATHS_REGISTRY: Record = { - chrome: "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe", - edge: "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\msedge.exe" +/** 用户级 AppData\Local 目录;LOCALAPPDATA 缺失(如受限启动环境)时退回 USERPROFILE 拼接 */ +function localAppDataDir(): string { + 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 = { + 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 { @@ -84,20 +99,22 @@ function queryRegistry(command: string): Promise { }); } -/** 探测本机浏览器安装路径:常见目录优先,注册表 App Paths 兜底 */ +/** 探测本机浏览器安装路径:常见目录优先,注册表 App Paths(HKLM/HKCU)兜底 */ export async function detectBrowserPath(browserType: ExternalBrowserType): Promise { for (const candidate of BROWSER_CANDIDATE_PATHS[browserType]) { if (await fileExists(candidate)) return candidate; } - try { - const stdout = await queryRegistry(BROWSER_APP_PATHS_REGISTRY[browserType]); - const match = stdout.match(/REG_SZ\s+(\S[^\r\n]*)/); - if (match) { - const registryPath = match[1].trim(); - if (await fileExists(registryPath)) return registryPath; + for (const registryKey of BROWSER_APP_PATHS_REGISTRIES[browserType]) { + try { + const stdout = await queryRegistry(registryKey); + const match = stdout.match(/REG_SZ\s+(\S[^\r\n]*)/); + if (match) { + const registryPath = match[1].trim(); + if (await fileExists(registryPath)) return registryPath; + } + } catch { + // 该键不存在继续查下一个 } - } catch { - // 注册表查询失败继续走报错 } throw new RuntimeError( "browser_not_found",