8.9 KiB
8.9 KiB
开发提示词:窗口内 3D —— WebView2 内嵌新迪查看器(方案 B)
用途:把本文件交给 AI 会话执行。任务完成后按"验收标准"逐条核对,并把结果回写 OnebotCatalog\项目总览.md(进展记录 + 踩坑表 + 最后更新行)。 背景必读:OnebotCatalog\项目总览.md(§12 新迪查看器联动)、OnebotCatalog\src\App\MainWindow.cs、OnebotCatalog\src\App\LocalViewerServer.cs。
一、角色与任务
你是资深 WPF/桌面软件工程师,在既有项目 OnebotCatalog(C# / .NET Framework 4.8,代码式 WPF,零 XAML)上实现:真实 CAD 数模(STEP)在软件窗口内直接显示 3D,不再弹出外部浏览器。
二、现状(先读懂再动手)
当前桌面 3D 显示链(src\App\MainWindow.cs 的 TryUpdateSelection() / TryLegacyRender() / FallbackToBrowser() / OpenBrowser3D()):
- 占位简化几何(自产极简 STEP)→ 内置
ViewerControl自绘渲染(窗口内) - 真实数模且有 STL 网格侧车(
<数据包目录>\mesh\<step同名>.stl,见FindMeshSidecar)→ 开源 Helix Toolkit 窗口内直渲(已实现,2026-08-23) - 真实数模且无网格 → 当前弹出外部浏览器(
Process.Start(url)+LocalViewerServer本机微型服务器 + 本地新迪查看器副本viewer\STEPViewer\)
本次目标:把第 3 条从"弹外部浏览器"改成"窗口内嵌 WebView2 加载同一 URL"。第 1、2 条保持不动。
三、硬性约束(违反即返工)
- 完全离线:WebView2 加载的是本机 127.0.0.1 微型服务器的 URL,无任何外网请求
- 目标平台 Win10/11 x64;客户机免安装(发布目录拷走即用)
- 编译环境:无 .NET SDK,只有 VS 2022 Build Tools 的 csc.exe + .NET Framework 4.8(
tools\build.ps1已封装,新增引用只能加 DLL/reference,不能用 csproj/NuGet 还原) - 编辑任何含中文的 .cs/.ps1 后必须跑
sample-data\tools\fix-bom.ps1(csc 对无 BOM 文件按 GBK 读取) - 客户版与开发版同一套代码(
#if CUSTOMER_BUILD区分);新功能两版都要生效 - 不碰
Z:\web\FTP_ObjectStorage\上海新迪3D\dev原项目(只读红线) - 不改动既有数据管线(catalog\ / .opc / publish 六步),本次只动桌面 3D 显示层与发布附带
四、实施步骤(严格按序)
步骤 1:引入 WebView2 控件库(需用户已批准下载)
- 下载 NuGet 官方源包 Microsoft.Web.WebView2(最新稳定版,确认
lib\net462\目标;.NET 4.8 兼容 net462) - 解出三个文件放进
OnebotCatalog\lib\:Microsoft.Web.WebView2.Wpf.dll(WPF 控件)Microsoft.Web.WebView2.Core.dllWebView2Loader.dll(native 加载器,分 x86/x64:anycpu 程序在 x64 系统跑 64 位,须放 x64 版本与 exe 同目录;必要时 build.ps1 里按位宽复制)
tools\build.ps1:$refs追加两个托管 DLL;编译成功后把两个托管 DLL + WebView2Loader.dll 复制到输出目录(现有 Helix DLL 复制的同一位置照抄)tools\publish.ps1:发布目录复制同样的 DLL(照抄现有 Helix DLL 复制行)
步骤 2:MainWindow 3D 标签页加 WebView2 控件
- 字段:
Microsoft.Web.WebView2.Wpf.WebView2 _webView2; - 在
grid3d(3D 标签页 Grid)中创建,初始Visibility = Visibility.Collapsed;背景与 Helix 视口一致(浅灰) - 初始化顺序(WebView2 特有坑):
EnsureCoreWebView2Async()完成前不能设置Source、不能调用 Core 属性;构造时先InitializeAsync():CoreWebView2Environment.CreateAsync(null, userDataFolder),userDataFolder用%LOCALAPPDATA%\OnebotCatalog\WebView2(离线无权限问题),环境带默认浏览器开关- 初始化失败(WebView2 Runtime 未安装)→ 捕获异常置
_webView2Available = false→ 走降级(见步骤 3)
- 窗口关闭时
Dispose()释放(OnClosed或Closed事件)
步骤 3:显示优先级重构(核心逻辑)
TryUpdateSelection() 中 3D 分支改为四级优先链,每级失败自动降级:
1. FindMeshSidecar 有网格 → Helix 窗口内直渲(现有 LoadHelixMesh)
2. 真实 B-rep 且 WebView2 可用 → _webView2.Source = LocalViewerServer 的 URL(新建),不 Process.Start
3. 真实 B-rep 且 WebView2 不可用 → 现有浏览器回退面板(FallbackToBrowser 保持原样)
4. 占位简化几何 → 内置 ViewerControl 自绘(现有 TryLegacyRender 逻辑)
OpenBrowser3D拆成两件事:GetPreviewUrl()(PublishStep 返回 URL,纯函数)与OpenBrowser3D(Process.Start 打开)。WebView2 分支只调用前者- 每次切换型号:WebView2 分支要隐藏 Helix 视口与回退面板、显示
_webView2;其他分支反过来 - 状态栏文案:窗口内显示时提示"已在窗口内显示真实数模 3D(WebView2)",与英文对照
_lang.T(zh, en)
步骤 4:WebView2 可用性检测与降级
- Runtime 检测(二选一,双保险):①
EnsureCoreWebView2Async抛异常即不可用;② 启动时查注册表HKLM\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}的 pv 值存在 - 不可用 → 3D 分支走第 3 级(浏览器回退面板),体验与现在一致;状态栏提示"未检测到 WebView2 运行时,使用浏览器预览(Win11 自带,Win10 装 Edge 即有)"
步骤 5:发布与交付
publish.ps1发布目录附带 WebView2 三件套 DLL(步骤 1)- 发布目录
README_zh.txt增加一行:Win10 若提示缺少 WebView2 运行时,安装 Edge 或微软 WebView2 Evergreen 运行时即可(可选附离线安装包到发布目录webview2\) - 客户版与开发版行为一致
步骤 6:回归验证
bin\OnebotCatalog.exe --selftest sample\OnebotCatalog_2026.08.opc→ 31 项全过(本次不改数据,必须不变)- 编译开发版 + 客户版都成功;
tools\publish.ps1全流程过 - 人工验收清单(见下节)逐条过,结果写进项目总览进展记录
五、验收标准(人工,逐条核对)
- 打开开发版 → 选「气动夹紧缸 UCBM → 规格 32」(真实数模、无网格场景要先临时移走
sample\mesh\UCBM32.stl验证):3D 在软件窗口内显示,无任何浏览器窗口弹出;拖拽旋转/滚轮缩放正常;剖切/线框/透明/视角/测量按钮可用(menu=min 精简菜单) - 移回网格后选同一型号:窗口内 Helix 渲染优先(画面切换无闪烁)
- 选占位型号(如 UCBM25):仍是内置自绘渲染,无 WebView2 介入
- 客户版发布目录双击运行:同 1~3 行为一致;完全断网验证(拔网线/禁网卡)可用
- 状态栏提示文案中英切换正确(右上角语言切换按钮)
- 关闭窗口进程干净退出(无残留 OnebotCatalog.exe)
六、已知陷阱(本项目血泪史 + WebView2 专属)
| # | 陷阱 | 对策 |
|---|---|---|
| 1 | PowerShell/csc 把无 BOM 中文文件按 GBK 读 → 乱码报错 | 改完必跑 fix-bom.ps1(步骤见约束 4) |
| 2 | GUI 子系统 exe 用 & 启动后 PowerShell 不等待,$LASTEXITCODE 空 |
一律 Start-Process -Wait -PassThru,核对 build.log/selftest.log 时间戳 |
| 3 | WebView2 在 EnsureCoreWebView2Async 完成前设置 Source/属性 → 崩溃 |
全部操作放在 await 之后;初始化失败路径显式处理 |
| 4 | WebView2Loader.dll 位宽不匹配 → 创建控件时 TypeInitializationException | anycpu + x64 系统用 x64 loader;发布时按位宽复制正确版本 |
| 5 | userDataFolder 无权限(Program Files 等)→ 初始化失败 | 用 %LOCALAPPDATA%\OnebotCatalog\WebView2 |
| 6 | 发布前程序/服务器占文件 → 复制失败 | 发布前停 serve-web 和运行中的 exe(红线) |
| 7 | 无头自动化难验 WebView2 渲染 | 用人工验收清单 + 降级路径自动测试;WebView2 失败必须静默降级到浏览器方案 |
| 8 | 新迪查看器 file 参数已改为站点根绝对路径 /step/...(踩坑 #20) |
LocalViewerServer 的 URL 构造保持现状,不要改回相对路径 |
七、交付物清单
- 可运行的开发版 exe(bin\)+ 客户版 exe(release 目录)
lib\新增 WebView2 三件套;build.ps1 / publish.ps1 相应改动- MainWindow.cs 改动(含注释,风格与现有代码一致)
- 文档回写:项目总览.md(进展记录新条目 + 踩坑表新增 WebView2 相关 + §12 更新 + 最后更新行)、docs\维护手册.md §7、README.md 已知简化段、数据维护说明书.md 桌面 3D 相关说明
- 本文件验收标准逐条核对结果
八、不做的事(范围外)
- 不碰网页版(web\ 与 release\web_2026.08)
- 不改数据管线与 .opc 格式
- 不做 WebView2 离线运行时安装器(只附可选安装包说明)
- 不把 WebView2 用于除 3D 标签页以外的任何界面