Skip to content

desktop: fall back to Edge browser folder when WebView2 Runtime is missing - #10

Merged
shaohaozhi286 merged 1 commit into
masterfrom
claude/debug-acecode-crash-XNWgr
May 11, 2026
Merged

shaohaozhi286 merged 1 commit into
masterfrom
claude/debug-acecode-crash-XNWgr

Conversation

@shaohaozhi286

Copy link
Copy Markdown
Collaborator

背景

很多企业 / 信创环境的机器只装了 Microsoft Edge 浏览器,而没有单独安装 "Microsoft Edge WebView2 Runtime"(独立 Evergreen Runtime,注册路径 HKLM\...\EdgeUpdate\Clients\{F3017226-...})。这种状态下:

  1. acecode-desktop 调 webview::webview ctor → 内部 CreateCoreWebView2EnvironmentWithOptions 找不到 Runtime → 抛 webview::exception
  2. WebHost::Impl 仅对"offscreen → nullptr"做了一层 fallback,nullptr 路径再失败时直接裸抛
  3. wWinMain 没有顶层 try/catch → std::terminate → Windows 弹"未经处理的异常"调试器对话框

普通用户既看不懂也无从下手。同事 / IT 反馈"已经装了 webview2 / Edge 也没用"时,这就是根因。

方案

WebView2Loader 公开了 WEBVIEW2_BROWSER_EXECUTABLE_FOLDER 环境变量(等价于 CreateCoreWebView2EnvironmentWithOptions 的 browserExecutableFolder 参数),而 Edge 100+ 浏览器目录里都自带同版本的 msedgewebview2.exe + 配套 dll,可以直接复用 —— 零打包代价(对比 Fixed Version Runtime 要 +180MB)。

策略:正常路径优先,失败再 fallback Edge 目录,对装了 Evergreen Runtime 的正常用户零行为变化。

改动

新增

  • src/desktop/webview2_runtime_probe.{hpp,cpp} — Edge 浏览器目录探测器

    • find_edge_browser_folder_in(roots):纯函数,接受根目录列表 → 扫 <root>/Microsoft/Edge/Application/<4 段版本号>/msedgewebview2.exe → 返回最新版本所在目录(按数值比较,跨 root 全局最大)
    • find_edge_browser_folder():Win32 系统调用版,用 SHGetKnownFolderPath 拿 ProgramFiles + ProgramFiles(x86) 调上面纯函数;POSIX 上 stub 返回 nullopt
    • 过滤 SetupMetrics / Installer / 非 4 段版本号目录;跳过版本目录在但 msedgewebview2.exe 缺失的情况(Edge channel 切换残留)
  • tests/desktop/webview2_runtime_probe_test.cpp — 8 个 GoogleTest 用例,覆盖纯函数:

    • 空 roots / 根目录无 Edge → nullopt
    • 单版本 + 多版本数值排序(字典序陷阱:"99.0.1.1" vs "100.0.1.1")
    • 非版本目录过滤
    • 缺 exe 跳过
    • 跨多 root 全局最新

修改

  • src/desktop/web_host.cpp::WebHost::Impl::Impl — 三段式构造:

    1. 默认 Loader 路径(优先 offscreen custom_window,失败切 nullptr 重试 — 沿用原降级)
    2. (1) 整段还抛 → 调 find_edge_browser_folder() → SetEnvironmentVariableW(WEBVIEW2_BROWSER_EXECUTABLE_FOLDER) → 重试构造
    3. Edge fallback 仍失败 / 没找到 Edge → show_webview2_failure_message_box 弹中文 MessageBox 给用户可执行的修复指引(装 Runtime / 删 EBWebView / 杀软白名单),LOG_ERROR 落盘后 ExitProcess(1)
  • src/desktop/main.cpp::wWinMain — IIFE lambda 包整个 body + 顶层 try / catch (std::exception&) / catch (...),兜底任何其他启动期未捕获异常,落 LOG_ERROR + 中文 MessageBox + return 1,避免再有"无声秒退"。

CMake 集成

零变更:

  • src/desktop/webview2_runtime_probe.cpp 不在 ACECODE_DESKTOP_BINARY_ONLY_SOURCES 列表 → 自动进 acecode_testable → acecode-desktop 通过 target_link_libraries(acecode-desktop PRIVATE acecode_testable) 拿到
  • acecode_testable 在 Win32 已 link shell32(folder_picker 用),SHGetKnownFolderPath 不需要额外 link
  • tests/desktop/webview2_runtime_probe_test.cpp 由 tests/CMakeLists.txt 的 GLOB_RECURSE *_test.cpp 自动拾取

验证

  • POSIX 路径下 webview2_runtime_probe.cpp g++ -std=c++17 编译通过
  • 用合成临时目录树(SetupMetrics + 100.0.x + 131.0.x + 缺 exe 的 99.0.x)运行 probe 函数,行为符合预期(选 131,跳过 SetupMetrics 和缺 exe 的目录)
  • Linux 环境无 vcpkg + 无 Windows SDK,完整 acecode-desktop 构建需要在 Windows 验证;Win32 路径主要风险点已审:括号匹配 / MessageBoxW 调用 / SetEnvironmentVariableW UTF-16 / lambda capture

Test plan

  • Windows 构建 acecode-desktop 正常通过(-DACECODE_BUILD_DESKTOP=ON)
  • acecode_unit_tests 跑 Webview2RuntimeProbe.* 全绿
  • 在装了 Evergreen Runtime 的正常机器上启动 acecode-desktop,日志确认未走 fallback 分支
  • 在只装 Edge 没装 Runtime 的机器上启动 acecode-desktop,日志看到 [desktop] retrying WebView2 with Edge browser folder: ...,窗口正常起来
  • 在没有 Edge 也没有 Runtime 的机器上启动,弹中文 MessageBox 给修复指引,而不是 Windows 调试器对话框

Generated by Claude Code

…ssing

很多企业 / 信创环境的机器只装了 Microsoft Edge 浏览器,而没有单独安装
"Microsoft Edge WebView2 Runtime"。现状下 acecode-desktop 走 WebView2Loader
默认 Runtime 发现路径直接抛 webview::exception,被 wWinMain 一路裸抛触发
Windows "未经处理的异常" 调试器对话框 — 普通用户既看不懂也无从下手。

WebView2Loader 公开了 WEBVIEW2_BROWSER_EXECUTABLE_FOLDER 环境变量(等价于
CreateCoreWebView2EnvironmentWithOptions 的 browserExecutableFolder 参数),
而 Edge 100+ 浏览器目录里都自带同版本的 msedgewebview2.exe,可以直接复用
避免分发 ~180MB 的 Fixed Version Runtime。

新增 src/desktop/webview2_runtime_probe.{hpp,cpp},暴露纯函数
find_edge_browser_folder_in(roots) + Win32 系统调用版
find_edge_browser_folder()。Impl ctor 被改成三段式:默认 Loader → Edge
浏览器目录 fallback → 终态 MessageBox + ExitProcess(1)。wWinMain 同时包顶层
try/catch 兜底任何其他启动期异常,避免再有"无声秒退"。

测试覆盖纯函数版本(版本号字典序陷阱、缺 exe 跳过、跨 root global latest 等)。
@shaohaozhi286
shaohaozhi286 merged commit 06f9770 into master May 11, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants