ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

.NET MAUI 源码仓库开发调试实战指南:从 Sandbox 复现问题到 Helix 设备测试

.NET MAUI 源码仓库开发调试实战指南:从 Sandbox 复现问题到 Helix 设备测试 .NET MAUI 源码仓库开发调试实战指南从 Sandbox 复现问题到 Helix 设备测试【免费下载链接】maui.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.项目地址: https://gitcode.com/GitHub_Trending/ma/maui本篇指南基于 .NET MAUI 开源仓库中的 docs/DevelopmentTips.md 编写面向希望在.NET MAUI 框架源码层面进行复现问题、断点调试、本地构建与云端设备测试的开发者。全文涵盖如何用 VS Code 打开仓库工作区并选择目标设备、如何借助 Sandbox 示例项目直接引用源码打断点、dotnet cake系列工具命令的用法、用build.sh/build.cmd在本地.dotnet目录自举 SDK 与工作负载、MSBUILDDEBUGONSTART调试 MSBuild Task 的完整流程以及如何把设备测试提交到 Helix 云基础设施并行执行。读完本文你将具备一套从本地复现 bug到云端验证修复的完整工程能力。一、快速开始用 VS Code 打开仓库并选择测试设备1.1 打开仓库工作区. .NET MAUI 仓库根目录自带 maui.code-workspace 工作区文件其内容将仓库根目录作为一个文件夹并预设了默认解决方案{ folders: [ { path: . } ], settings: { dotnet.defaultSolution: Microsoft.Maui-vscode.sln } }在 VS Code 中直接打开本地克隆的 .NET MAUI 仓库根目录即可VS Code 会自动检测到该 workspace 文件并提示你打开它选择 Open Workspace 即可。工作区预设的默认解决方案是 Microsoft.Maui-vscode.sln这是专为 VS Code 场景裁剪的解决方案避免直接加载完整的 Microsoft.Maui.sln 而拖慢 IntelliSense 初始化。小贴士第一次打开后IntelliSense 及其他后台任务可能需要约一分钟才能完成初始化。如果项目尚未安定下来直接使用命令面板执行任务可能会出现 Pick Startup Project has resulted in an error. 的报错稍等片刻再试即可。1.2 通过 Pick Device 选择目标设备在 VS Code 中使用命令面板Windows/Linux 为Ctrl Shift PmacOS 为Command Shift P输入pick device第一次选择时会列出平台选项Android、iOS、Mac Catalyst、Windows 等先选中你要运行的平台在接下来的菜单中选择该平台下当前可用的具体设备模拟器、模拟器镜像或本机设备。仓库中的 .vscode/tasks.json 也提供了Run Sample任务其底层命令形如./bin/dotnet/dotnet build ${input:project} -t:Run -f ${input:framework} -c ${input:configuration} -p:AndroidAttachDebugger${input:attach}其中-t:Run表示构建后直接部署运行-f指定目标框架如net7.0-android-p:AndroidAttachDebugger决定是否在启动时挂接 Android 调试器——这与你用命令面板手动选设备的流程本质一致只是通过任务菜单驱动。二、用 Sandbox 示例项目复现问题并调试框架源码2.1 Sandbox 是什么仓库中的src/Controls/samples/Controls.Sample.Sandbox是一个刻意保持空的示例应用其核心价值在于直接引用 .NET MAUI 源码工程而非打包后的 NuGet 包。查看其项目文件 Maui.Controls.Sample.Sandbox.csproj 可以看到ItemGroup Condition $(UseMaui) ! true ProjectReference Include..\..\..\Core\src\Core.csproj / ProjectReference Include..\..\..\Controls\src\Xaml\Controls.Xaml.csproj / ProjectReference Include..\..\..\Controls\src\Core\Controls.Core.csproj / ProjectReference Include..\..\..\BlazorWebView\src\Maui\Microsoft.AspNetCore.Components.WebView.Maui.csproj / ProjectReference Include..\..\..\Controls\Maps\src\Controls.Maps.csproj / ProjectReference Include..\..\..\Controls\Foldable\src\Controls.Foldable.csproj / /ItemGroup也就是说当UseMaui ! true即不使用全局安装的 MAUI workload时Sandbox 会以ProjectReference方式引用Core、Controls.Core、Controls.Xaml、BlazorWebView、Maps、Foldable 等源码工程。这意味着你可以在.NET MAUI 框架源码里直接下断点逐行步进到控件渲染、布局、绑定等内部实现在 Sandbox 页面里粘贴你遇到的复现代码即可在可控的最小工程中观察框架行为。Sandbox 工程本身还包含MainPage.xaml、SandboxShell.xaml等页面文件以及 Android/iOS/MacCatalyst/Windows/Tizen 各平台入口属于一个完整的 MAUI 单项目SingleProjecttrue应用随时可以往里面加页面与代码。2.2 将 Sandbox 设为启动项目要让 VS Code 知道你要运行的是 Sandbox使用命令面板CtrlShiftP或 macOSCommandShiftP输入pick startup选择.NET MAUI: Pick Startup Project然后在列表中选择Controls.Sample.Sandbox工程。之后配合第一节的 Pick Device 流程即可把 Sandbox 部署到你选定的设备/模拟器上运行。2.3 提交 PR 的注意事项重要Sandbox 属于个人复现环境提交 Pull Request 时不要把你对 Sandbox 工程的改动一并提交例如临时加进去的复现代码、调试输出等。你可以用git status检查改动范围只提交与问题修复相关的源码与测试改动。三、Cake 工具命令仓库根目录的日常瑞士军刀以下参数均可配合dotnet cake命令在仓库根目录使用。它们属于工具性命令日常开发中若只需准备 .NET SDK 与 workload官方更推荐直接使用./build.sh -restoreWindows 用./build.cmd -restore——这一点详见第四节。3.1--targetpublicapi重建公共 API 清单dotnet cake --targetpublicapi作用清空并重新生成所有 MAUI 工程的PublicAPI.Unshipped.txt文件覆盖 Core、Controls、Essentials、Graphics 四大模块。适用场景当你新增了公共 API 却收到缺少 API 声明类编译错误时运行一次即可自动补齐。平台处理非 Windows 环境自动跳过 Windows 专属文件且始终跳过 Tizen 文件以及 macOS 专属文件。其实现位于 eng/cake/dotnet.cake 的Task(publicapi)脚本会依次扫描src/Core/src/PublicAPI、src/Controls/src/Core/PublicAPI、src/Essentials/src/PublicAPI、src/Graphics/src/Graphics/PublicAPI目录下的所有PublicAPI.Unshipped.txt清空后以PublicApiTypeGenerate属性重新构建Controls.Core.csproj以回填当前实际 API。这些清单文件在仓库中真实存在例如 src/BlazorWebView/src/Maui/PublicAPI 下按net-android、net-ios、net-tizen、net-windows、net等目标框架各有一份PublicAPI.Shipped.txt与PublicAPI.Unshipped.txt。3.2--clean清理本地增量构建缓存dotnet cake --clean问题背景切换分支或同步 main 分支后增量构建偶尔会坏掉出现莫名其妙的编译或链接错误。常见粗暴解法git clean -xdf删除全部本地缓存但代价是未提交的改动也会被一并抹掉。推荐解法使用--clean递归删除本地各工程的obj/bin目录既清除了缓存又保留你的未提交修改。3.3 指定目标平台--android/--ios/--windows/--catalystdotnet cake --targetVS --workloadsglobal --android --ios上面的命令表示以全局 workload 方式准备 .NET构建并启动 Visual Studio同时只启用 Android 与 iOS 两个平台。注意如果你在项目里新增或更换了平台需要先执行git clean -xdf彻底清理后重新构建否则新旧平台的残留产物会互相干扰。四、Blazor Hybrid若要构建并运行 Blazor Desktop即 Blazor Hybrid / Blazor WebView for Desktop示例请查阅仓库内 Blazor WebView 相关示例工程例如 src/BlazorWebView/samples/BlazorWinFormsApp、src/BlazorWebView/samples/BlazorWpfApp 与共享的 src/BlazorWebView/samples/WebViewAppShared。这些工程演示了如何在 WinForms / WPF 中承载 Blazor WebView、如何使用RootComponent注册 Razor 组件以及如何做 JS 互操作。具体构建运行方式以对应工程及仓库 src/BlazorWebView 目录下的源码说明为准。五、高级场景用本地.dotnet自举构建整个仓库5.1 推荐方式build.sh/build.cmd这是官方推荐的 .NET SDK 与 workload 准备方式底层基于 Arcade 构建基础设施。仓库根目录提供了 build.sh 与 build.cmd 脚本以及配套的eng/common工具链。第一步恢复 .NET SDK 与 workload 到本地.dotnet目录./build.sh -restoreWindows 下.\build.cmd -restore第二步可选同时构建解决方案./build.sh -restore -build.\build.cmd -restore -build第三步可选打包 NuGet 包./build.sh -restore -pack.\build.cmd -restore -pack执行-restore后本地的 SDK 会落在.dotnet目录后续所有./bin/dotnet/dotnet ...形式的命令都使用这套自举 SDK从而保证构建的是当前分支的源码而非已发布的正式包。5.2 通过 Cake 目标启动 IDE仓库的 eng/cake/dotnet.cake 定义了VS、VSCode、Insiders三个 IDE 启动目标它们都会先执行Clean→dotnet自举 SDK→dotnet-buildtasks构建 MSBuild Task→dotnet-pack按需打包再以自举的 .NET 环境变量启动 IDEdotnet tool restore dotnet cake --targetVS启动 VS Codedotnet tool restore dotnet cake --targetVSCode从源码看StartVisualStudioForDotNet()在 Windows 上通过VSWhereLatest找到最新版 Visual Studio 并打开Microsoft.Maui-windows.slnf非 Windows 上则打开Microsoft.Maui-mac.slnf同时注入DOTNET_INSTALL_DIR、DOTNET_ROOT、PATH等环境变量确保 IDE 内部使用的就是本地.dotnet见 dotnet.cake 中的SetDotNetEnvironmentVariables。5.3 用--sln把分支改动实测到你的项目上如果你想知道某个分支的修改能否解决你遇到的问题可以用--sln参数让 MAUI 先完成打包再用本地包打开你的解决方案dotnet tool restore dotnet cake --slndownload_directory\MauiApp2\MauiApp2.sln --targetVS注意打包只在第一次运行时自动执行如果你改了代码需要重新打包必须显式加上--pack标志。5.4--pack把分支改动装进本地 dotnetdotnet tool restore dotnet cake --targetVS --pack --slndownload_directory\MauiApp2\MauiApp2.sln--pack会在本地 dotnet 安装目录内生成 .NET MAUI 的 pack包括模板改动此后你就能用本地 dotnet 的 CLI 命令创建/部署应用并且所有行为都基于当前分支的改动。用新 pack 创建一个全新 MAUI 应用dotnet tool restore dotnet cake --pack mkdir MyMauiApp cd MyMauiApp ..\bin\dotnet\dotnet new maui ..\bin\dotnet\dotnet build -t:Run -f net[current_sdk_version]-android其中net[current_sdk_version]指代当前 SDK 对应的目标框架版本仓库 dotnet.cake 中的DefaultDotnetVersion默认值为net10.0请以你本地eng/Versions.props实际版本为准。5.5 拆开跑的完整命令序列如果不希望走完整 Cake 流程也可以按顺序手动执行# 1. 安装本地构建工具cake、pwsh 等 dotnet tool restore # 2. 在 bin\dotnet 中自举 .NET SDK dotnet build src\DotNet\DotNet.csproj # 3. 构建 MAUI 的 MSBuild Tasks .\bin\dotnet\dotnet build Microsoft.Maui.BuildTasks.slnf # 4. 构建其余全部 MAUI 代码 .\bin\dotnet\dotnet build Microsoft.Maui.sln # 5. 启动 Visual Studio dotnet cake --targetVS注意这些命令大多依赖步骤 2 自举出的bin\dotnet里的 SDK因此顺序不能颠倒dotnet tool restore负责把仓库 .config 下声明的本地工具Cake 等恢复到.config/dotnet-tools.json指定的版本。六、调试 MSBuild Tasks让构建停下来等你挂调试器MSBuild Task 在构建进程内部执行常规方式很难断点调试。.NET MAUI 仓库的做法是利用MSBUILDDEBUGONSTART环境变量将其设为2时MSBuild 会在继续执行前阻塞并等待调试器连接控制台会输出类似Waiting for debugger to attach (dotnet PID 13001). Press enter to continue...之后在 IDE 中挂接到该 PID再回到命令行按回车放行即可从断点处逐步调试 Task 代码。6.1 各平台启动命令macOSMSBUILDDEBUGONSTART2 ~/some maui checkout/dotnet-local.sh build -m:1LinuxMSBUILDDEBUGONSTART2 ~/some maui checkout/dotnet-local.sh build -m:1Windowsset MSBUILDDEBUGONSTART2 ~/some maui checkout/dotnet-local.cmd build -m:1-m:1非常关键它把 MSBuild 限制为单节点否则调试器挂接的进程可能与实际执行 Task 的进程不一致导致断点不命中。若当前 checkout 中不存在dotnet-local.sh/dotnet-local.cmd仓库快照中未包含该脚本可改用自举出的./bin/dotnet/dotnet或./.dotnet/dotnet配合同样的环境变量执行build -m:1。6.2 在 IDE 中挂接进程Visual Studio打开Microsoft.Maui.sln解决方案使用菜单Debug → Attach to Process选择输出提示中的 dotnet PID。VS Code打开仓库工作区使用Run and Debug面板中的Attach to Process选项输入 PID 后连接。连接成功后回到命令行按Enter让 MSBuild 继续。此后你可以在Task 代码中设置断点并单步执行注意Target 是 MSBuild 脚本无法断点只有 C# 编写的 Task 可以。6.3 在 VS Code 里自动填充如果你在 VS Code 中进行 in-tree 调试可以使用Build Platform Sample命令——它会询问你是否调试 MSBuild Tasks并自动为你填好MSBUILDDEBUGONSTART。查看 .vscode/tasks.json 可以看到Build Platform Sample任务的debugbuildtasks输入项正好提供与MSBUILDDEBUGONSTART2两个选项选择后者即可。启动后 PID 文本会出现在 VS Code 的Terminal面板中再用Attach to Process挂接即可。七、集成测试构建与运行 MAUI 模板集成测试工程位于src/TestUtils/src/Microsoft.Maui.IntegrationTests它包含构建并/或运行 MAUI 模板或其他项目的测试。仓库中的 dotnet.cake 也内置了dotnet-integration-build与dotnet-integration-test两个 Cake 目标。你既可以在 VS 的测试资源管理器Test Explorer中运行也可以从命令行用dotnet test精确指定某个测试dotnet test src/TestUtils/src/Microsoft.Maui.IntegrationTests --logger console;verbositydiagnostic --filter NameBuild\(\maui\,\net7.0\,\Debug\,False\)说明--logger console;verbositydiagnostic输出诊断级日志便于观察模板创建与构建过程的每一步--filter NameBuild(...)按方法名精确过滤注意方法名中的括号与引号在命令行里需要转义该测试的本质是用指定版本的模板创建一个maui应用在 Debug 配置下构建并验证是否成功——这也是检验分支改动是否破坏模板的最直接手段。八、在 Helix 上运行设备测试.NET MAUI 支持借助 .NET Engineering Services 的Helix基于 XHarness把设备测试分发到云端的真实设备/模拟器上并行执行。Helix 提供跨平台、多设备的云端测试基础设施本地构建好测试包后提交上去即可在 CI 或自用场景下大规模跑设备测试。8.1 涉及哪些设备测试工程仓库中参与 Helix 的测试工程包括工程覆盖范围Controls.DeviceTestsUI 控件测试Core.DeviceTests核心框架测试Graphics.DeviceTests图形与绘制测试Essentials.DeviceTests平台 API 测试MauiBlazorWebView.DeviceTestsBlazor WebView 测试它们对应的源码分别在 src/Controls/tests/DeviceTests、src/Core/tests/DeviceTests、src/Graphics/tests/DeviceTests、src/Essentials/test/DeviceTests 与 src/BlazorWebView/tests/DeviceTests。8.2 Helix 队列当前配置以仓库 eng/helix_xharness.proj 为准使用的队列如下iOSosx.15.arm64.open对外开源队列Mac Catalystosx.15.arm64.openAndroidubuntu.2204.amd64.android.33.open源码中的实际队列定义更为细致开放场景与内部场景分开HelixTargetQueues Condition$(TargetOS) iososx.15.arm64.maui.open;osx.26.arm64.open/HelixTargetQueues HelixTargetQueues Condition$(TargetOS) maccatalystosx.15.arm64.maui.open;osx.26.arm64.open/HelixTargetQueues HelixTargetQueues Condition$(TargetOS) androidubuntu.2204.amd64.android.33.open/HelixTargetQueues HelixTargetQueues Condition$(TargetOS) windowswindows.11.amd64.client.open/HelixTargetQueues即 iOS/Mac Catalyst 使用 macOS ARM64 队列同时保留内部HelixInternalTrue时的专用队列Android 使用 Ubuntu Android 33 模拟器队列Windows 场景还支持windows.11.amd64.client.open。具体可用队列请以 Helix 服务端实时列表为准。8.3 本地三步走构建 → 打包 → 提交以下命令默认在仓库根目录执行。Step 1构建 MSBuild Tasks必做# 恢复 dotnet 工具 dotnet tool restore # 构建 MSBuild Tasks必需的前置步骤 ./build.sh -restore -build -configuration Release -projects $(PWD)/Microsoft.Maui.BuildTasks.slnf /bl:BuildBuildTasks.binlog -warnAsError false/bl:BuildBuildTasks.binlog用于输出二进制构建日志-warnAsError false避免历史告警直接导致失败。Step 2构建设备测试工程# 为所有平台构建设备测试 ./build.sh -restore -build -configuration Release /p:BuildDeviceTeststrue /bl:BuildDeviceTests.binlog -warnAsError false/p:BuildDeviceTeststrue是触发设备测试工程参与构建的属性开关。Step 3提交到 Helix先设置 Helix 所需的 CI 环境变量export BUILD_REASONpr export BUILD_REPOSITORY_NAMEmaui export BUILD_SOURCEBRANCHmain export SYSTEM_TEAMPROJECTdnceng export SYSTEM_ACCESSTOKEN然后分别按目标平台提交# 提交 Android 设备测试 ./eng/common/msbuild.sh ./eng/helix_xharness.proj /restore /p:TreatWarningsAsErrorsfalse /t:Test /p:TargetOSandroid /bl:sendhelix_android.binlog -verbosity:diag # 提交 iOS 设备测试 ./eng/common/msbuild.sh ./eng/helix_xharness.proj /restore /p:TreatWarningsAsErrorsfalse /t:Test /p:TargetOSios /bl:sendhelix_ios.binlog -verbosity:diag # 提交 Mac Catalyst 设备测试 ./eng/common/msbuild.sh ./eng/helix_xharness.proj /restore /p:TreatWarningsAsErrorsfalse /t:Test /p:TargetOSmaccatalyst /bl:sendhelix_catalyst.binlog -verbosity:diag核心是 eng/helix_xharness.proj 这个 MSBuild 项目它根据TargetOS选择队列与测试场景自动从artifacts/bin/发现各设备测试工程的产物MAUIScenario自动发现机制并以 XHarness 定义每个 work item 的TestTarget如ios-simulator-64、maccatalyst。8.4 Windows 命令Windows 开发环境使用对应的.cmd文件set BUILD_REASONpr set BUILD_REPOSITORY_NAMEmaui set BUILD_SOURCEBRANCHmain set SYSTEM_TEAMPROJECTdnceng set SYSTEM_ACCESSTOKENREM 构建 MSBuild Tasks .\build.cmd -restore -build -configuration Release -projects .\Microsoft.Maui.BuildTasks.slnf /bl:BuildBuildTasks.binlog -warnAsError false REM 构建设备测试 .\build.cmd -restore -build -configuration Release /p:BuildDeviceTeststrue /bl:BuildDeviceTests.binlog -warnAsError false REM 提交到 Helix以 Android 为例 .\eng\common\msbuild.cmd .\eng\helix_xharness.proj /restore /p:TreatWarningsAsErrorsfalse /t:Test /p:TargetOSandroid /bl:sendhelix.binlog -verbosity:diag8.5 配置细节eng/helix_xharness.proj 是 Helix 配置的核心主要包含超时设置work item 超时 2 小时、测试超时 1 小时iOS 上个别按类别拆分的 Controls 测试还额外配置了LaunchTimeout10 分钟定义于各XHarnessAppBundleToTest项的WorkItemTimeout/TestTimeout/LaunchTimeout元数据测试发现通过MAUIScenario自动发现每个场景的测试包遍历artifacts/bin/下的Controls.DeviceTests、Core.DeviceTests等目录平台定位每个平台对应特定目标框架TargetFrameworkToTest与 XHarnessTestTarget队列选择按TargetOS与HelixInternal选择开放的*.open队列或内部专用队列XHarness 集成通过IncludeXHarnessCli引入 XHarness 完成设备编排Windows 目标不使用 XHarness故IncludeXHarnessClifalse。8.6 常见问题排查构建失败请先确认已经完成 Step 1构建 MSBuild TasksHelix 提交依赖最新的 Task 二进制找不到设备/队列不可用检查目标队列如ubuntu.2204.amd64.android.33.open在 Helix 服务端是否可用认证失败CI 场景下请确保设置了正确的 Azure DevOps 访问令牌SYSTEM_ACCESSTOKEN超时默认超时比较宽松但复杂测试场景如长时间 UI 交互可能需要按需调大WorkItemTimeout/TestTimeout。日志与诊断建议始终使用/bl:文件名.binlog生成二进制日志配合dotnet msbuild /bl或其他 binlog 查看工具定位构建阶段问题提交 Helix 时追加-verbosity:diag获取最大诊断输出提交完成后根据 Helix 返回的作业 URL 查看运行结果与设备日志。8.7 与 CI 的集成设备测试已接入仓库 CI 流水线主要通过以下文件eng/pipelines/common/stage-device-tests.yml流水线模板定义设备测试阶段eng/test-configuration.json测试重试配置满足条件的 PR 构建会自动触发设备测试无需人工干预。从 eng/helix_xharness.proj 的队列定义可以看出同一套提交逻辑既服务于内部 CIHelixInternalTrue的专用队列也面向开源贡献者*.open队列这正是 .NET MAUI 社区化测试协作的基础设施保障。九、总结围绕 docs/DevelopmentTips.md 的内容本文完整覆盖了 .NET MAUI 仓库开发的四类核心场景本地复现与断点调试VS Code 工作区 Pick Device Sandbox 工程直接引用源码日常工具命令dotnet cake的publicapi、clean、平台参数以及build.sh/build.cmd的自举构建、--sln、--pack分支实测流程构建系统级调试用MSBUILDDEBUGONSTART2让 MSBuild 等待调试器进而单步调试 Task 代码云端设备测试从本地构建设备测试包到提交 Helix 并行执行再到基于 eng/helix_xharness.proj 的配置与排障。掌握了这条链路你就拥有了从在框架源码里复现一个 bug到用云端设备矩阵验证修复的完整工作流这也是参与 .NET MAUI 社区开发最常用的实战路径。【免费下载链接】maui.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.项目地址: https://gitcode.com/GitHub_Trending/ma/maui创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表