- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
WinUI 3 (以下简称 WinUI)框架发布后的二进制文件过大的问题存在了很长时间,我在 这篇文章 中有过详细的讨论,好在 Windows App SDK v1.2 就已经支持剪裁发布,但是我却一直没有成功实现,直到最近才发现了问题所在.
在 WinUI 上使用云母或亚克力材质的时候,一般会照抄 微软文档中提供的方法 。问题就出在这,这一页最后更新于 2022-09-24,那时 WinUI 还不支持剪裁,文档中的方法自然不会有问题.
// 仅包含关键代码
class WindowsSystemDispatcherQueueHelper
{
// ...
object m_dispatcherQueueController = null;
[DllImport("CoreMessaging.dll")]
private static extern int CreateDispatcherQueueController([In] DispatcherQueueOptions options, [In, Out, MarshalAs(UnmanagedType.IUnknown)] ref object dispatcherQueueController);
// 此方法在设置云母或亚克力前调用
public void EnsureWindowsSystemDispatcherQueueController()
{
// ...
if (m_dispatcherQueueController == null)
{
DispatcherQueueOptions options;
// ...
CreateDispatcherQueueController(options, ref m_dispatcherQueueController);
}
}
}
在这里通过 P/Invoke 调用了一个外部 COM 函数,而开启剪裁后,编译器会警告: Trim analysis warning IL2050: P/invoke method 'WindowsSystemDispatcherQueueHelper.CreateDispatcherQueueController' declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed. 剪裁后无法保证 COM 互操作的正确性,可能会删除接口和接口成员。事实证明剪裁后确实出错了.
查看函数 CreateDispatcherQueueController 的定义,第二个参数返回的是一个指针,同时我们也不关心 COM 对象内容的细节,那解决方法就很简单,使用 IntPtr 替换 object 即可.
HRESULT CreateDispatcherQueueController(
[in] DispatcherQueueOptions options,
[out] PDISPATCHERQUEUECONTROLLER *dispatcherQueueController
);
修改后的代码如下:
class WindowsSystemDispatcherQueueHelper
{
// 改为 nint
nint m_dispatcherQueueController;
[DllImport("CoreMessaging.dll")]
// 删除互操作相关的特性
private static extern int CreateDispatcherQueueController(in DispatcherQueueOptions options, out nint dispatcherQueueController);
public void EnsureWindowsSystemDispatcherQueueController()
{
if (m_dispatcherQueueController == 0)
{
DispatcherQueueOptions options;
_ = CreateDispatcherQueueController(options, out m_dispatcherQueueController);
}
}
}
在最新的 Windows App SDK v1.3 实验版 1 中引入了新的 API,大大简化了设置背景材质的流程,并且这个新 API 不存在上述问题.
WinUI 支持了剪裁,这为我们发布小体积应用创造了条件,不过这里的坑也很多.
需要注意的是, .NET 7 修改了 剪裁粒度 的默认值,默认剪裁全部程序集,所以发布时一定要把 TrimMode 设置为 partial 。这是一个比较粗糙的解决办法,可能有更优的方案,但是我没有深入研究.
WinUI 运行依赖 Windows App Runtime ,这个组件没有内置在系统中,并且更新还很频繁。当发布为 Msix 包时,无论是否上架微软商店,安装应用的过程中商店服务都会自动下载并安装 Runtime(可能会因为网络问题安装失败)。但是不上架商店的 Msix 包安装起来就很麻烦,发布为非打包的二进制程序更为合适.
发布为非打包的二进制程序时,可以选择是否包含 Windows App Runtime,如果不包含并且按照以下设置发布:
<!-- 不打包 -->
<WindowsPackageType>None</WindowsPackageType>
<!-- 启用剪裁 -->
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>partial</TrimMode>
<!-- 自包含 .NET 运行时 -->
<SelfContained>true</SelfContained>
<!-- 单文件 -->
<PublishSingleFile>true</PublishSingleFile>
<!-- 关闭 ReadyToRun -->
<PublishReadyToRun>false</PublishReadyToRun>
<!-- 不包含 Windows App Runtime -->
<WindowsAppSDKSelfContained>false</WindowsAppSDKSelfContained>
<!-- 压缩发布的文件 -->
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
<!-- 单文件包含原生库 -->
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
空模板项目最终生成三个文件,“小而美”,但是运行后会弹窗提醒下载安装 Windows App Runtime ,在这个网页中没有引导真的很难找到正确的下载链接.
如果选择发布时包含 Windows App Runtime,就不能在发布的单文件中包含原生库,否则会出现无法打开的情况,相关讨论 参考 issue 。结果就是发布后的文件很繁杂,整个 Runtime 都在发布文件夹中,并且还存在着非常多的语言相关文件夹。经过我的测试只需要保留 en-us 和 Microsoft.UI.Xaml 这两个文件夹,删除其他文件夹不影响使用。这样一个空模板项目的大小最终是 58 MB.
没有总结.
最后此篇关于WinUI剪裁发布中的一个小坑的文章就讲到这里了,如果你想了解更多关于WinUI剪裁发布中的一个小坑的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我们正在使用 VSTS 构建和发布通过 Xamarin 创建的 iOS 和 Android 应用程序。通过 VSTS 将 Android 应用发布到商店相对简单。有人可以指导我或提供一些如何通过 VS
我一直在研究 Spring Social Facebook 的 publish(objectId, connectionName, data) API ,但不确定此 API 的用法(遗憾的是,由于缺少
我正在使用 django viewflow 创建一个发布流程: 用户创建对象 它进入审核流程,其状态为待处理(公众不可见) 经过审核和批准后,就会发布并公开可见。 如果用户编辑同一实体,则会再次进入审
我正在尝试进行 API 调用,并且 API 需要格式为 XML: Security GetSessionInfo 999999999999 0 2 {
我已经查看了所有 StackOverflow,但没有找到适合我的案例的解决方案我有 405 HttpStatusCode 调用 API/Regions/Create 操作这是我的 baseContro
如果我切换到新版本的SpringBoot,我在启动应用程序时会得到上面的错误信息。这是为什么? 最美好的祝愿史蒂文 pom.xml 4.0.0 de.xyz.microservice spring
我有一个场景,页面导航是从一个域到另一个域完成的。例如,导航是从 http://www.foo.com到 http://www.bar.com在 JavaScript 中单击按钮 重定向时,我需要将用
这半年来一直深耕包头,这个城市比较不错,但是推进项目的难度确实挺大的。与开发产品相比,后者更省心。但是光研发产品,没有项目
我正在阅读有关 Github 版本 的信息,它似乎很适合您的项目。因为我们需要决定将哪些功能用于生产,哪些不用于。 我无法理解的部分是,master 和 release 分支如何在其中发挥作用。 Sh
我将一些代码推送到远程存储库,然后在 GitHub 上创建了第一个版本,并将其命名为 'v0.0.1'。 GitHub 现在显示我现在有一个版本,并且还在“标签”中显示我有一个标签 “v0.0.1”。
如果我有一个具有以下文件/文件夹结构的 GitHub 存储库 github.com/@product/template: /build /fileA /fileB /src /genera
我有一个 Maven 多模块项目。 当代码开发完成后,我们想在 Jenkins 中编写一个分支构建作业,它分支代码,增加主干中的 pom 版本,并删除 -SNAPSHOT 来自分支中的 pom 版本。
我有一个非常大的集合(约 40000 个文档,包含约 20-25 个字段,包括包含一组约 500 个项目的数组字段)和约 2000 个订阅者(他们现在只是机器人)。 因此,当用户订阅整个集合(不包括服
如果我正在使用消息队列构建一个包含数十个发布者/订阅者的系统,那么我似乎有一些网络配置选项: 我可以拥有一个所有机器都使用的集群代理 - 每台机器都没有本地队列 我可以在每台机器上本地安装代理,并使用
我正在使用 Flash Develop,并且创建了一个 ActionScript 3.0 项目。它启动并读取一个 xml 文件,其中包含图像的 url。我已将 url 保留在与 swf 相同的文件夹中
如果我在一个句子中使用 alloc 和 retain 声明一个 NSArray 那么我应该释放 NSArray 对象两次(即[arrayObject release] 2次)? 最佳答案 如果您在同一
我正在尝试在 Node 中实现发布/订阅模式,但不使用 Redis。功能应该是相同的;您可以发布到 channel ,订阅 channel 并收听数据(如果您已订阅);以下是 Redis 功能: pu
编辑:这个问题、一些答案和一些评论,包含很多错误信息。见 how Meteor collections, publications and subscriptions work准确理解发布和订阅同一服
我正在开发一款 DirectX 游戏,我发现在发布版本中我的平均帧速率为 170fps,但是在调试版本中我的帧速率约为 20fps。 我想知道发布和调试版本之间的巨大差异是否正常,特别是因为在调试中我
是否有办法回滚 Windows Azure 网站和 SQL 部署/发布? 我发布了一个网站,现在它导致了很多错误,我想回到之前的状态并进一步处理代码。 这可能吗? 最佳答案 如果您使用 Git 或 T
我是一名优秀的程序员,十分优秀!