恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
.NET MAUI Workload 深度解析:UseMaui 属性体系、Workload Id 与本地构建安装实战
首页
资讯中心
/
.NET MAUI Workload 深度解析:UseMaui 属性体系、Workload Id 与本地构建安装实战
.NET MAUI Workload 深度解析:UseMaui 属性体系、Workload Id 与本地构建安装实战
发布时间:2026/9/13 18:52:24
.NET MAUI Workload 深度解析UseMaui 属性体系、Workload Id 与本地构建安装实战【免费下载链接】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 Workload 是 .NET 6 引入的全新 SDK 扩展机制而 .NET MAUI 正是通过它把跨平台 UI 框架以按需可裁剪的方式分发到 Android、iOS、Mac Catalyst、Windows 与 Tizen。本文以 src/Workload/README.md 为骨架结合仓库中的WorkloadManifest.in.json、BundledVersions.in.targets、DotNet.csproj等真实实现系统讲解$(UseMaui)隐式包引入机制、九个 Workload Id 的继承关系、$(MauiVersion)的版本覆盖原理以及从源码构建、系统级安装到 CI 验证、环境清理和 NuGet 中心包管理的完整实战流程。读完本文你将能独立理解 .NET MAUI 的打包分发架构并掌握在本机与 CI 中构建、安装、验证 MAUI Workload 的全部命令。一、$(UseMaui)一个属性撬动整个 MAUI 框架.NET Workload 是 .NET 6 中引入的新概念它让一个普通项目仅通过设置一个 MSBuild 属性就能自动获得整套框架的 SDK、模板和运行库。在 .NET MAUI 中这个入口属性就是$(UseMaui)Project SdkMicrosoft.NET.Sdk PropertyGroup TargetFrameworksnet6.0-android;net6.0-ios/TargetFrameworks OutputTypeExe/OutputType UseMauitrue/UseMaui /PropertyGroup /Project当$(UseMaui)为true时Workload 会自动引入以下四个组成部分组成部分作用Microsoft.NET.Sdk.MauiWorkload manifest工作负载清单描述 workload 与 pack 的树状关系Microsoft.Maui.SdkWorkload SDK真正包含 MSBuild targets/props 的入口包Microsoft.Maui.ControlsMAUI Controls 根 NuGet 包聚合 Controls.Core、Xaml、Build.TasksMicrosoft.Maui.Templates当前构建对应的项目模板集从 manifest 看包的真实构成清单文件 src/Workload/Microsoft.NET.Sdk.Maui.Manifest/WorkloadManifest.in.json 中maui-core是一个abstract抽象workload它列出了$(UseMaui)背后真正的 pack 全集Microsoft.Maui.Sdk、Microsoft.Maui.Graphics、Microsoft.Maui.Resizetizer、Microsoft.Maui.Templates、Microsoft.Maui.Core、Microsoft.Maui.Controls、Microsoft.Maui.Controls.Build.Tasks、Microsoft.Maui.Controls.Core、Microsoft.Maui.Controls.Xaml、Microsoft.Maui.Essentials。也就是说UseMaui并不只带来四个包而是通过 workload 的extends继承关系递归展开出一整套依赖树——这正是 Workload 机制的威力所在。二、BlazorWebView用.Razor后缀扩展 SDKBlazorWebView 是 MAUI 的一个重要附加组件。项目可以通过在Sdk属性上追加.Razor来按需启用Project SdkMicrosoft.NET.Sdk.Razor这会将$(UsingMicrosoftNETSdkRazor)置为 true从而触发 MAUI workload 额外引入Microsoft.AspNetCore.Components.WebView.Maui源码中的隐式包引用逻辑在 src/Workload/Microsoft.Maui.Sdk/Sdk/BundledVersions.in.targets 中可以看到隐式包引用的真实实现_MauiImplicitPackageReference IncludeMicrosoft.AspNetCore.Components.WebView.Maui Version$(MauiVersion) Condition $(UseMaui) true and $(UsingMicrosoftNETSdkRazor) true 即只有同时满足UseMauitrue与UsingMicrosoftNETSdkRazortrue两个条件Blazor 组件包才会被隐式加入。随后这些依赖会被自动转换为PackageReference IncludeMicrosoft.AspNetCore.Authorization / PackageReference IncludeMicrosoft.AspNetCore.Components.WebView / PackageReference IncludeMicrosoft.AspNetCore.Components.WebView.Maui / PackageReference IncludeMicrosoft.JSInterop /从 BundledVersions.in.targets 的实现看隐式引用采用先收集到_MauiImplicitPackageReference再用Remove(PackageReference)去掉用户已显式声明的包最后统一注入的策略因此用户显式写出的 PackageReference 永远不会与隐式引用冲突。三、细粒度控制UseMauiAssets、UseMauiCore、UseMauiEssentials对于 .NET 6 项目如果不想引入完整的 Microsoft.Maui.Controls可以按需选取 MAUI 的部分能力按属性逐级订阅MSBuild 属性引入的包$(UseMauiAssets)Microsoft.Maui.Resizetizer跨平台资源生成与集成工具$(UseMauiCore)Microsoft.Maui.Core所有 MAUI 功能的基础接口与 Handler$(UseMauiEssentials)Microsoft.Maui.Essentials与框架无关的跨平台 API 集这三个属性与$(UseMaui)一起构成了 MAUI 的能力订阅体系。在 BundledVersions.in.targets 中每个属性都有独立的注入条件_MauiImplicitPackageReference IncludeMicrosoft.Maui.Resizetizer Version$(MauiVersion) PrivateAssetsall Condition $(UseMauiAssets) true / _MauiImplicitPackageReference IncludeMicrosoft.Maui.Essentials Version$(MauiVersion) Condition $(UseMauiEssentials) true 注意Resizetizer始终以PrivateAssetsall注入——因为它只是构建期工具不应被下游项目传递引用而Essentials、Core、Controls在OutputType Library非 Android 应用、非应用扩展时同样会设置PrivateAssetsall避免类库项目把 MAUI 运行时依赖泄露给消费方。关于$(UseMauiNuGets)的历史兼容BundledVersions.in.targets 的注释明确说明旧的、已不受支持的$(UseMauiNuGets)属性在语义上等同于新的$(DisableMauiImplicitPackageReferences)仅为兼容历史项目而保留新项目不应再使用它。四、Workload 的三个特殊文件.NET MAUI Workload 由三个关键文件驱动理解它们就理解了整个分发链路1.AutoImport.props— 占位但不可或缺文件位于 src/Workload/Microsoft.Maui.Sdk/Sdk/AutoImport.props内容只有一个空Project /。它是 MSBuild 约定的 Workload 必备文件会被所有.NET 6 项目类型导入——包括非移动项目。它将来用于定义 MAUI 项目的默认 include通配符目前只是必须存在的占位符。2.WorkloadManifest.json— workload 配置树这是 .NET SDK 识别 MAUI Workload 的依据。仓库中以模板形式维护WorkloadManifest.in.json构建时把VERSION、MAUI_DOTNET_VERSION等占位符替换为实际版本。它声明了两大块内容workloads 节定义maui、maui-mobile等 workload Id 及其extends关系packs 节定义每个 pack 的kindsdk/library/template、版本以及alias-to平台别名例如Microsoft.Maui.Graphics.Windows在 win-x86/x64/arm64 下分别别名到Microsoft.Maui.Graphics.Win2D.WinUI.Desktop。3.WorkloadManifest.targets— 进入 SDK 的入口模板位于 WorkloadManifest.in.targets。它同样被所有.NET 6 项目类型导入即使是非移动项目。它的核心职责是当$(UseMaui)或UseMauiCore/UseMauiEssentials/UseMauiAssets为 true且目标框架版本匹配时导入Sdk.targetsSDK 包为Microsoft.Maui.Sdk.net{主版本}从而激活 MAUI 构建链。它还会注册一系列ProjectCapability如UseMaui、UseMauiCore供 IDE 和遥测判断用户是否指定了某个UseMaui*属性但 Workload 未正确安装。此外针对上一个 .NET 主版本目标它会用$(MauiVersion)覆盖Microsoft.Maui.Core、Microsoft.Maui.Controls、Microsoft.Maui.Essentials三个KnownFrameworkReference的运行时与目标包版本。从 manifest 到 SDK 的导入链Microsoft.Maui.Sdk包内的 Sdk.targets 是真正的链接点Import ProjectBundledVersions.targets / Import ProjectMicrosoft.Maui.Sdk.targets Condition $(UseMaui) true or $(UseMauiCore) true /BundledVersions.targets由BundledVersions.in.targets生成设置MauiWorkloadVersion、默认$(MauiVersion)等版本属性并按UseMaui*属性隐式注入 NuGet 包Microsoft.Maui.Sdk.targets框架 targets 的真正起点依次导入Before.targetsrestore 前的属性设置、$(MicrosoftMauiSdkPlatformTargets)中声明的平台 targets并把Microsoft.Maui.Sdk.After.targets排入$(AfterMicrosoftNETSdkTargets)队列用于在最后补齐ProjectCapability供 IDE 判断如何恢复项目。这套 targets / Before.targets / After.targets 的四段式结构以及 Workload 与各 NuGet 包中 props/targets 的摆放策略在 docs/design/NuGets.md 中有更详细的专文说明。五、.NET MAUI Workload Id 全景在 .NET 中一个 workload 就是一组 pack 的集合。.NET MAUI 根据需要装什么提供了多个 workload IdWorkload Id说明maui全部平台maui-mobileiOS Android含 Tizenmaui-desktopMac Catalyst Windowsmaui-core所有平台必需的基础包maui-androidAndroid 平台maui-maccatalystMac Catalyst 平台maui-macosmacOS 平台maui-windowsWindows 平台maui-tizenTizen 平台这些 Id 之间存在清晰的继承关系。从 WorkloadManifest.in.json 的extends字段可以看到真实的依赖树maui→ extendsmaui-mobilemaui-desktopmaui-mobile→ extendsmaui-androidmaui-iosmaui-tizenmaui-desktop→ extendsmaui-maccatalystmaui-windowsmaui-android→ extendsmaui-blazorandroid即直接扩展现有androidworkload叠加 MAUI 的 Android 平台实现maui-ios/maui-maccatalyst→ extendsmaui-blazor 对应的ios/maccatalystworkloadmaui-blazorabstract→ extendsmaui-core额外包含Microsoft.AspNetCore.Components.WebView.Maui包maui-windows→ extendsmaui-blazor额外包含Microsoft.Maui.Graphics.Windows包一个关键结论这些 Id 并不与 Visual Studio Installer 中工作负载的概念一一对应。从开发者的视角选择mobile、maui或desktop最终拿到的东西如下图所示图中可以直观看到mobile/desktop选项只覆盖各自对应的平台子集而maui以及 MAUI SDK覆盖全部平台——这是理解 Visual Studio 安装器选项与 .NET workload Id 关系的关键。六、$(MauiVersion)按项目覆盖 Workload 版本当前 .NET MAUI workload 按 .NET SDK 版本带band并排安装例如dotnet/sdk-manifests/6.0.100/microsoft.net.sdk.maui/为了获得更大的灵活性你可以在.csproj中显式指定版本MauiVersion8.0.100-preview.1.2345/MauiVersion即使系统没有全局安装8.0.100-preview.1.2345只要在.csproj中写上这个属性就能在构建期与运行期针对较新的 .NET MAUI 程序集进行构建。其底层原理在 BundledVersions.in.targets 中SDK 会先设置MauiWorkloadVersion即当前已安装 workload 的版本而$(MauiVersion)仅在未被显式赋值时回退到MauiWorkloadVersion——也就是说用户显式声明的MauiVersion优先于 workload 自带版本且所有隐式 PackageReference 都以Version$(MauiVersion)注入从而实现了一个属性统管全部包版本的效果。七、本地构建并体验 Workload从源码到 Samples1. 先构建出 nupkg在仓库根目录执行# Restore .NET SDK and workloads, then pack ./build.sh -restore -packWindows 下使用.\build.cmd -restore -pack构建完成后会得到artifacts/*.nupkg各种包文件同时把必要的文件复制到./bin/dotnet即仓库本地私有化的 dotnet 运行时目录。2. 用 Workload 模式构建 Samples默认情况下仓库内的 samples 是通过ProjectReference/直接引用源码工程来构建的。而 workload 模式则改为使用刚产出的 nupkg 包$ git clean -dxf src/Controls/samples/ $ ./bin/dotnet/dotnet build ./eng/Microsoft.Maui.Samples.slnf -p:UseWorkloadtrue-p:UseWorkloadtrue是关键开关它会用 Workload 替代工程文件中声明的 ProjectReference。从 src/Workload/Microsoft.Maui.Sdk/Sdk/Sdk.targets 的导入链可以看到正是BundledVersions.targets把隐式 PackageReference 注入项目从而让 workload 驱动构建 成为可能。八、系统级安装 Workload拿到artifacts/*.nupkg后可以安装到系统级 dotnet 目录macOS 为/usr/local/share/dotnet/Windows 为C:\Program Files\dotnet\。macOS 下需要 sudo$ sudo dotnet build src/DotNet/DotNet.csproj -t:InstallWindows 下请在管理员命令提示符中执行 dotnet build src/DotNet/DotNet.csproj -t:InstallDotNet.csproj会把 workload 安装到当前正在运行 dotnet 命令的那个实例中。查看 src/DotNet/DotNet.csproj 的Installtarget 实现其流程是从artifacts/Microsoft.NET.Sdk.Maui.Manifest-*.nupkg解压出data/*即WorkloadManifest.json与WorkloadManifest.targets通过内联的CopyWorkloadFiles任务复制到sdk-manifests/{版本带}/microsoft.net.sdk.maui/把artifacts目录注册为本地 NuGet 源执行dotnet workload install mauiLinux 上为避免 iOS/macOS 依赖安装的是maui-android若设置IncludeTizenTargetFrameworkstrue还会追加tizen使用--skip-sign-check --skip-manifest-update跳过签名校验与清单更新。因此本地./.dotnet安装无需管理员权限而系统级安装则必须在 Windows 管理员命令行或 macOS 的 sudo 下执行。九、CI 中的 Workload 测试流程dotnet/maui 的 CI 采用最小化预装、按需装配的策略来验证 workload 本身第一步将.nupkg下载到artifacts并用-p:InstallWorkloadPacksfalse预置一个不带移动端 workload packs的 .NET 6 环境$ dotnet build src/DotNet/DotNet.csproj -p:InstallWorkloadPacksfalse在 DotNet.csproj 中可以看到InstallWorkloadPacks默认值为true只有显式关闭时_InstallWorkloadPacks目标才会被跳过从而只装 SDK 不装 packs。第二步用Installtarget 从artifacts/*.nupkg解压安装 workload$ ./bin/dotnet/dotnet build src/DotNet/DotNet.csproj -t:Install第三步以 workload 模式构建 samples 验证$ ./bin/dotnet/dotnet build ./eng/Microsoft.Maui.Samples.slnf -p:UseWorkloadtrue这套provision装 SDK→ Install装 workload→ UseWorkload 构建三段式流程正是验证脱离源码引用、纯 NuGet 分发是否自洽的标准做法。十、清理被搞坏的 .NET 6 安装与 Workload当 .NET 6 安装状态异常hosed时可以按下面的方法卸载 .NET 6 与所有 workload 以彻底重来。默认安装位置WindowsC:\Program Files\dotnet\macOS/usr/local/share/dotnet/Windows 上先到Control Panel控制面板Programs and Features程序和功能卸载 .NET 6——但卸载后仍会残留文件macOS 没有真正的.pkg卸载方式因此只能手动删除文件。然后手动删除以下目录dotnet/library-packs dotnet/metadata dotnet/packs/Microsoft.Android.* dotnet/packs/Microsoft.iOS.* dotnet/packs/Microsoft.MacCatalyst.* dotnet/packs/Microsoft.macOS.* dotnet/packs/Microsoft.Maui.* dotnet/packs/Microsoft.tvOS.* dotnet/sdk/6.0.100-* dotnet/sdk-manifests dotnet/template-packs这些目录都是 .NET 6 专属的删除它们不会影响 .NET 5 及更早版本。清理完成后即可重新进行全新安装。十一、NuGet Central Package ManagementCPM集中管理版本如果你希望把 .NET MAUI 的全部依赖版本集中到一处管理可以启用 NuGet 的中央包管理Central Package Management功能。首先创建一个Directory.Packages.props文件Project PropertyGroup ManagePackageVersionsCentrallytrue/ManagePackageVersionsCentrally MauiVersion8.0.3/MauiVersion MicrosoftExtensionsVersion8.0.0/MicrosoftExtensionsVersion /PropertyGroup ItemGroup PackageVersion IncludeMicrosoft.Maui.Core Version$(MauiVersion) / PackageVersion IncludeMicrosoft.Maui.Controls Version$(MauiVersion) / PackageVersion IncludeMicrosoft.Maui.Controls.Core Version$(MauiVersion) / PackageVersion IncludeMicrosoft.Maui.Controls.Build.Tasks Version$(MauiVersion) / PackageVersion IncludeMicrosoft.Maui.Controls.Xaml Version$(MauiVersion) / PackageVersion IncludeMicrosoft.Maui.Essentials Version$(MauiVersion) / PackageVersion IncludeMicrosoft.Maui.Resizetizer Version$(MauiVersion) / PackageVersion IncludeMicrosoft.Extensions.Logging.Debug Version$(MicrosoftExtensionsVersion) / /ItemGroup /Project$(MauiVersion)与$(MicrosoftExtensionsVersion)需要替换为真实存在的版本号可以从 NuGet 上的Microsoft.Maui.Sdk包页或 dotnet/maui 的 GitHub Releases 页面获取有效版本。这两个属性完全是可选的——你也可以直接把版本号写进%(PackageVersion.Version)的 item 元数据中。然后在 .NET MAUI 应用程序的.csproj中PackageReference故意不写 VersionPackageReference IncludeMicrosoft.Maui.Core / PackageReference IncludeMicrosoft.Maui.Controls / PackageReference IncludeMicrosoft.Maui.Essentials / PackageReference IncludeMicrosoft.Maui.Resizetizer / PackageReference IncludeMicrosoft.Extensions.Logging.Debug /%(PackageReference.Version)留空是刻意为之版本统一由Directory.Packages.props中的PackageVersion项提供。关于此特性的更多细节可参考微软官方的 NuGet Central Package Management 文档。与隐式引用的协作机制这里有一个容易被忽视的细节CPM 模式下BundledVersions.in.targets 会自动把$(DisableMauiImplicitPackageReferences)置为 true。也就是说启用 CPM 后MAUI 不再隐式注入任何 PackageReference所有包都必须由你在.csproj中显式声明如上例版本则由中央的PackageVersions统一裁决。如果漏写了某个包构建时会触发ValidateMauiImplicitPackageReferences目标的 MA002 警告可通过SkipValidateMauiImplicitPackageReferencestrue跳过提示你补上对应的 PackageReference。结语从$(UseMaui)一行属性到maui/maui-mobile/maui-desktop九个 workload Id 的继承树从MauiVersion的按项目覆盖到src/DotNet/DotNet.csproj的Install目标.NET MAUI 的 workload 机制把框架分发这件事做成了可裁剪、可并排安装、可本地复现的标准流程。无论是想深入理解 MAUI 的构建架构还是需要在 CI 中自建 MAUI 分发验证本文涉及的属性、文件与命令配合 docs/design/NuGets.md 的 NuGet 结构说明都能作为你继续深入的第一手地图。【免费下载链接】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),仅供参考