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踩了不少 ...
随机推荐
- windows脚本bat做文件备份
@ECHO OFF echo 切换到当前目录... cd /d %~dp0% echo 开始复制Code1... echo d | XCOPY Code1 ..\备份\bakdir\Code1 /s ...
- DTCC 干货分享:Real Time DaaS - 面向TP+AP业务的数据平台架构
2021年10月20日,Tapdata 创始人唐建法(TJ)受邀出席 DTCC 2021(中国数据库技术大会),并在企业数据中台设计与实践专场上,发表主旨演讲"Real Time Daa ...
- 字符输出流_Writer类&FileWriter类介绍和字符输出流的基本使用_写出单个字符到文件
java.io.Writer:字符输出流,是所有字符输出流的最顶层的父类,是一个抽象类 共性的成员方法: - void write(int c) 写入单个字符 - void write(char[] ...
- python解决“failed to execute pyi_rth_pkgres”问题
pip uninstall pyinstaller pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip
- SQL练习六--More JOIN operations
movie Field name Type Notes id INTEGER An arbitrary unique identifier title CHAR(70) The name of the ...
- 【设计过程】.NET ORM FreeSql WhereDynamicFilter 动态表格查询功能
前言 最近几乎每天40度,越热越不想面对电脑,还好开源项目都比较稳定没那么多待解决问题,趁着暑假带着女儿学习游泳已略有小成.游泳好处太多了,建议有孩子的都去学学,我是在岸边指导大约一周左右就学会了,目 ...
- CodeQL使用流程
前言 好久没用CodeQL了,看了自己之前写的文章发现竟然没有做过相关记录 然后就不知道怎么用了hhh 使用流程 0x1 生成数据库 我们拿到一套源码,首先需要使用CodeQL生成数据库 执行命令: ...
- 简单的数据结构_via牛客网
题面 链接:https://ac.nowcoder.com/acm/contest/28537/K 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语 ...
- else语句
else的搭配 与else语句配合使用有三种情况 if ...: else: if条件表达式不成立的时候执行else 注意else还可以与while循环和for循环组合在一起(这是一个全新的知识) 注 ...
- 对象数组的foreach循环操作和集合容器
ForEach标签可以循环数组,list,map集合 采用 foreach循环遍历 ,并每次循环允许执行一次回调函数 for (容器中元素类型 临时变量: 容器变量) { System.out.pri ...