记录.Net 8 发布增加 PublishTrimmed 裁剪选项,调用WMI 的ManagementObject 异常
最近在做OTA的功能,需要获取到sn做一些业务的逻辑。我们自己实现的库里边的,大部分都是调用 System.Management 的 ManagementObjectSearcher 获取 Bios 的序列号
如下所示:
private void BtnWmi_OnClick(object sender, RoutedEventArgs e) { try { // 创建 WMI 查询 ManagementObjectSearcher searcher = new ManagementObjectSearcher( "SELECT SerialNumber FROM Win32_BIOS"); // 遍历查询结果 foreach (ManagementObject obj in searcher.Get()) { string serialNumber = obj["SerialNumber"]?.ToString(); if (!string.IsNullOrEmpty(serialNumber)) { Console.WriteLine($"BIOS 序列号: {serialNumber}"); return; } } Console.WriteLine("未找到 BIOS 序列号信息"); } catch (ManagementException ex) { Console.WriteLine($"WMI 查询错误: {ex.Message}"); } catch (Exception ex) { Console.WriteLine($"WMI 查询异常错误: {ex.Message}"); } }
由于我们项目现在新建的项目都是基于.Net 8 开发,而且为了兼容多种设备和系统,我们目前的打包方式都是以发布独立部署的方式
同时为了能减少输出文件的大小,我们会启用裁剪的方式 <PublishTrimmed>true</PublishTrimmed>
<PublishTrimmed>true</PublishTrimmed> <_SuppressWpfTrimError>true</_SuppressWpfTrimError> <BuiltInComInteropSupport>true</BuiltInComInteropSupport> <TrimMode>partial</TrimMode>
以上准备工作做好,发布以上的程序,运行发现如下的错误:
查询了官网的资料,有如下的说明:剪裁选项 - .NET | Microsoft Learn
就是启用裁剪会禁用掉某些框架的功能。
解决方法:
参考:使用 C# 远程连接到 WMI - Win32 apps | Microsoft Learn
使用 Microsoft.Management.Infrastructure 的 CimSession 替换WMI 早期的版本
如下所示:
using Microsoft.Management.Infrastructure; private void BtnCim_OnClick(object sender, RoutedEventArgs e) { try { // 创建本地CIM会话 using (var session = CimSession.Create(null)) { // 查询Win32_BIOS类 var instances = session.QueryInstances(@"root\cimv2", "WQL", "SELECT SerialNumber FROM Win32_BIOS"); foreach (var instance in instances) { var serialNumber = instance.CimInstanceProperties["SerialNumber"].Value?.ToString(); Console.WriteLine($"BIOS 序列号: {serialNumber}"); } } } catch (Exception ex) { Console.WriteLine($"错误: {ex.Message}"); } }
不修改发布选项的情况下,运行如下:是可以获取得到Bios的sn的
总结:
1、推荐使用 Microsoft.Management.Infrastructure 的 CimSession 替换 WMI 旧版的 ManagementObject
2、裁剪的选项 PublishTrimmed 如果不介意应用程序的一点体积,是可以忽略不加
参考:
1、剪裁选项 - .NET | Microsoft Learn