WinUI 3 踩坑记:从创建项目到发布
本文是 WinUI 3 踩坑记 的一部分,该系列发布于 GitHub@Scighost/WinUI3Keng,若内容出现冲突以 GitHub 上的为准。
创建项目
现在 WinUI 3 的入门体验比刚发布那会儿好太多了,至少不会再出现模板项目无法生成的情况 [1]。打开 Visual Studio 创建 WinUI 3 项目,有如下的三个模板可以选择:
第一个模板的 WinUI 3 项目和打包项目是同一个项目,第三个模板的则是两个不同的项目。如果在发布时需要让多个可执行文件存在于不同文件夹,就选择第三个模板。

打包与非打包
WinUI 3 默认创建打包项目,打包发布需要使用被用户设备信任的证书给包签名,如果要发布非打包的项目,在项目文件(*.csproj)中加入以下内容即可 [2]。
<!-- *.csproj -->
<PropertyGroup>
......
<!-- 不打包 -->
<WindowsPackageType>None</WindowsPackageType>
<!-- 自包含 Windows App SDK Runtime,否则需要单独安装 -->
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
</PropertyGroup>
优缺点
| 优点 | 缺点 | |
|---|---|---|
| 打包 | 操作系统保证包内文件不会被篡改 | 需要代码签名 |
| 非打包 | 部署灵活 | 无法使用与应用包有关的 API |
发布
创建项目后,会在文件夹 ./Properties/PublishProfiles/ 内创建三个不同 CPU 架构的发布配置文件,下面以 x64 平台的为例。
<!-- win10-x64.pubxml -->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Platform>x64</Platform>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
<!-- 自包含 .NET 运行时 -->
<SelfContained>true</SelfContained>
<!-- 不要发布为单个文件 -->
<PublishSingleFile>False</PublishSingleFile>
<!-- Release 配置时使用 ReadyToRun 编译 -->
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
<PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
<!-- 暂时不能使用剪裁 -->
<!--
See https://github.com/microsoft/CsWinRT/issues/373
<PublishTrimmed>True</PublishTrimmed>
-->
</PropertyGroup>
</Project>
自包含和 ReadyToRun 编译让 WinUI 3 安装包的体积不逊于 Electron,尽管现在硬盘空间很宽裕,但是在打包后还是要注意一下安装包的大小,因为第三方库可能会引入 WinForm 和 WPF 的框架文件。
这里以云之幻的网络回环管理器为例,项目中引用的第三方库仅有四个,但是安装包大小却有 90.3 MB。
<!-- LoopbackManager.App.csproj -->
<PackageReference Include="PInvoke.User32" Version="0.7.124" />
<PackageReference Include="ReactiveUI" Version="18.3.1" />
<PackageReference Include="ReactiveUI.Fody" Version="18.3.1" />
<PackageReference Include="ReactiveUI.WinUI" Version="18.3.1" />

打开安装后应用的文件夹,以文件大小排序,发现几个眼熟的东西,这不就是 WinForm 和 WPF 的吗。(图中仅截取了前几个,后面还有更多)

究其原因,在项目中有这样一条引用链:网络回环管理器 -> ReactiveUI -> DynamicData ->System.Reactive,而在 System.Reactive 的项目文件中有这样一段,导致在 WinUI 3 项目中会引入 WinForm 和 WPF 的框架文件。
<!-- System.Reactive.csproj -->
<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1' or $(TargetFramework.StartsWith('net5.0-windows'))">
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
<IncludeBuildOutput Condition="'$(TargetFramework)' == 'netcoreapp3.1'">false</IncludeBuildOutput>
</PropertyGroup>
可惜的是,除了不引用这些第三方库以外,我暂时还没有找到在打包项目中解决这个问题的办法。
不同条件下的应用大小
因为有可能会引入额外的框架文件,我测试了 WinUI 3 模板项目在不同发布条件下的大小,帮各位读者排排雷。
这里的 2W 是指 WinForm 和 WPF,在我的测试中,如果仅使用 UseWindowsForms 或 UseWPF ,额外引入的框架文件是一样的,所以不对二者进行区分。
WindowsAppSDK 是指项目文件中 WindowsAppSDKSelfContained = true 的情况,用户在安装打包项目的安装包时(msix 或 msixbundle 文件),系统会自动下载并安装 Windows App SDK Runtime。但是非打包项目没有这个福利,所以这一项仅供非打包项目参考。
| 安装包 | 安装后 | |
|---|---|---|
| WinUI | 40.4 MB | 101 MB |
| WinUI + ReadyToRun | 51.1 MB | 138 MB |
| WinUI + WindowsAppSDK | 59.6 MB | 155 MB |
| WinUI + WindowsAppSDK + ReadyToRun | 70.3 MB | 193 MB |
| WinUI + 2W | 75.5 MB | 188 MB |
| WinUI + 2W + ReadyToRun | 86.2 MB | 225 MB |
| WinUI + 2W + WindowsAppSDK | 94.7 MB | 242 MB |
| WinUI + 2W + WindowsAppSDK + ReadyToRun | 105.0 MB | 279 MB |
额外引入的内容
下表列出了额外引入 WinForm 和 WPF 框架时多出的文件或文件夹。
点击展开
| 文件或文件夹名称 |
|---|
| cs/ |
| de/ |
| es/ |
| fr/ |
| it/ |
| ja/ |
| ko/ |
| pl/ |
| pt-BR/ |
| ru/ |
| tr/ |
| zh-Hans/ |
| zh-Hant/ |
| Accessibility.dll |
| D3DCompiler_47_cor3.dll |
| DirectWriteForwarder.dll |
| Microsoft.VisualBasic.Forms.dll |
| Microsoft.Win32.Registry.AccessControl.dll |
| Microsoft.Win32.SystemEvents.dll |
| PenImc_cor3.dll |
| PresentationCore.dll |
| PresentationFramework.Aero.dll |
| PresentationFramework.Aero2.dll |
| PresentationFramework.AeroLite.dll |
| PresentationFramework.Classic.dll |
| PresentationFramework.dll |
| PresentationFramework.Luna.dll |
| PresentationFramework.Royale.dll |
| PresentationFramework-SystemCore.dll |
| PresentationFramework-SystemData.dll |
| PresentationFramework-SystemDrawing.dll |
| PresentationFramework-SystemXml.dll |
| PresentationFramework-SystemXmlLinq.dll |
| PresentationNative_cor3.dll |
| PresentationUI.dll |
| ReachFramework.dll |
| System.CodeDom.dll |
| System.Configuration.ConfigurationManager.dll |
| System.Design.dll |
| System.Diagnostics.EventLog.dll |
| System.Diagnostics.EventLog.Messages.dll |
| System.Diagnostics.PerformanceCounter.dll |
| System.DirectoryServices.dll |
| System.Drawing.Common.dll |
| System.Drawing.Design.dll |
| System.IO.Packaging.dll |
| System.Printing.dll |
| System.Resources.Extensions.dll |
| System.Security.Cryptography.Pkcs.dll |
| System.Security.Cryptography.ProtectedData.dll |
| System.Security.Cryptography.Xml.dll |
| System.Security.Permissions.dll |
| System.Threading.AccessControl.dll |
| System.Windows.Controls.Ribbon.dll |
| System.Windows.Extensions.dll |
| System.Windows.Forms.Design.dll |
| System.Windows.Forms.Design.Editors.dll |
| System.Windows.Forms.dll |
| System.Windows.Forms.Primitives.dll |
| System.Windows.Input.Manipulations.dll |
| System.Windows.Presentation.dll |
| System.Xaml.dll |
| UIAutomationClient.dll |
| UIAutomationClientSideProviders.dll |
| UIAutomationProvider.dll |
| UIAutomationTypes.dll |
| vcruntime140_cor3.dll |
| WindowsFormsIntegration.dll |
| wpfgfx_cor3.dll |
引用
- [1] WindowsAppSDK: .NET 6 and WINUI3 fails to start Unable to load DLL 'Microsoft.ui.xaml.dll'
- [2] 非 MSIX 打包:为非 MSIX 打包的 C# 或 C++ WinUI 3 桌面应用创建一个新项目
WinUI 3 踩坑记:从创建项目到发布的更多相关文章
- WinUI 3 踩坑记:前言
WinUI 3 (Windows App SDK 于 2021 年 11 月发布了第一个正式版 v1.0.0 [1],最新版本是 v1.1.5 [2].我的基于 WinUI 3 的个人项目 寻空 从年 ...
- WinUI 3 踩坑记:第一个窗口
本文是 WinUI 3 踩坑记 的一部分,该系列发布于 GitHub@Scighost/WinUI3Keng,文中的代码也在此仓库中,若内容出现冲突以 GitHub 上的为准. WinUI 3 应用的 ...
- ASP.NET+MVC入门踩坑笔记 (一) 创建项目 项目配置运行 以及简单的Api搭建
哈喽各位 我又回来了! 前段时间研究了下ASP.NET,刚开始也是随便找网上的各种教程来看,但是鉴于本人技术有限,还是走了相当长的一段弯路的.所以我写下了这篇文章.希望各位刚刚入坑的ASP.NET开发 ...
- Spark踩坑记——Spark Streaming+Kafka
[TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...
- Spark踩坑记——共享变量
[TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...
- Spark踩坑记——从RDD看集群调度
[TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...
- Spark踩坑记:Spark Streaming+kafka应用及调优
前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark streaming从k ...
- Vue + TypeScript + Element 搭建简洁时尚的博客网站及踩坑记
前言 本文讲解如何在 Vue 项目中使用 TypeScript 来搭建并开发项目,并在此过程中踩过的坑 . TypeScript 具有类型系统,且是 JavaScript 的超集,TypeScript ...
- centos 7( linux )下搭建elasticsearch踩坑记
原文:https://blog.csdn.net/an88411980/article/details/83150380 概述 公司最近在做全文检索的项目,发现elasticsearch踩了不少 ...
随机推荐
- 关于'utf-8' codec can't decode byte 0xb9 in position 0: invalid start byte报错
今天在使用vscode编译程序时,启动Python服务出现以下错误: 通过网络查找资料可以得知,是由于个人用户名非英文而导致,但是网上并没有说清楚是哪里的名字,以至于很多人会以为是以下地方: 实际上真 ...
- NC23046 华华教月月做数学
NC23046 华华教月月做数学 题目 题目描述 找到了心仪的小姐姐月月后,华华很高兴的和她聊着天.然而月月的作业很多,不能继续陪华华聊天了.华华为了尽快和月月继续聊天,就提出帮她做一部分作业. 月月 ...
- 机器学习基础:用 Lasso 做特征选择
大家入门机器学习第一个接触的模型应该是简单线性回归,但是在学Lasso时往往一带而过.其实 Lasso 回归也是机器学习模型中的常青树,在工业界应用十分广泛.在很多项目,尤其是特征选择中都会见到他的影 ...
- .NET服务治理之限流中间件-FireflySoft.RateLimit
概述 FireflySoft.RateLimit自2021年1月发布第一个版本以来,经历了多次升级迭代,目前已经十分稳定,被很多开发者应用到了生产系统中,最新发布的版本是3.0.0. Github:h ...
- labview从入门到出家5(进阶篇)--程序调试以及labview函数库的运用
跟了前面几章的操作流程,相信大家对labview有了一定的认识.其实只要了解了labview的编程思路,再熟悉地运用各个变量,函数以及属性,那么我们就可以打开labview的大门了.跟其他编程语言一样 ...
- CSS 浮动 (二)
CSS 浮动 本人是一名大二学生,欢迎大家进行交流 V15774135883 推荐一个是自学的网站 里面有超多培训机构的大课,地址 有需要可以加我免费拿! 传统网页布局的三种方式 网页布局的本质--用 ...
- c:找到出现次数最多的递增数字串
如题,如何在一亿位整数组成的字符串中找到出现次数最多的递增数字串? 答案: #include <stdio.h> #include <string.h> #define MAX ...
- 图文并茂演示小程序movable-view的可移动范围
前言 开发过小程序的同学可能对这两个内置组件并不陌生,他们配合用来实现在页面中可以拖拽滑动,其中: movable-area表示元素可移动的区域,它决定元素移动的区域范围 movable-view表示 ...
- 痞子衡嵌入式:MCUXpresso IDE下将源码制作成Lib库方法及其与IAR,MDK差异
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是MCUXpresso IDE下将源码制作成Lib库方法及其与IAR,MDK差异. 程序函数库是一个包含已经编译好代码和数据的函数集合,这 ...
- IO概述(概念&分类)和字节输入流+OUTputStream类&FileOutPutStream类介绍
IO概述 什么是IO 生活中,你肯定经历过这样的场景.当你编辑一个文本文件,忘记了保存,可能文件就白白编辑了.当你的电脑上插入一个U盘,可以吧一个视频,拷贝到你的电脑硬盘里,那么数据都是在哪些设备上的 ...