C#执行PowerShell脚本调用Get-BIOS命令返回空结果如何解决
问题根因分析
- 两次执行
scriptText用的是独立的PowerShell上下文,第一次安装的模块在第二次执行时已经失效,无法被识别 - 默认PowerShell运行空间禁止未信任的模块仓库执行安装操作,非交互环境下安装
GetBIOS模块会静默失败 - 原有代码只捕获了标准输出流,没有捕获错误、警告流,无法感知执行过程中出现的权限不足、模块未找到等报错
- 若本地测试用的是PowerShell 7+,而C#默认调用的是Windows PowerShell 5.1,两个环境的模块安装路径互相独立,也会导致模块找不到
修复方案
方案1:修正PowerShell调用逻辑
将模块安装、导入、命令执行合并到同一次执行上下文,同时添加错误流捕获,配置执行策略和仓库信任:
Runspace runspace = RunspaceFactory.CreateRunspace(); runspace.Open(); PowerShell ps = PowerShell.Create(); ps.Runspace = runspace; // 合并所有逻辑到同一个脚本,关闭执行策略限制、信任PSGallery、安装导入模块后执行命令 string scriptText = @" Set-ExecutionPolicy RemoteSigned -Scope Process -Force Set-PSRepository -Name PSGallery -InstallationPolicy Trusted if (-not (Get-Module -ListAvailable -Name GetBIOS)) { Install-Module -Name GetBIOS -Scope CurrentUser -Force -AllowClobber } Import-Module GetBIOS -Force Get-BIOS "; ps.Commands.AddScript(scriptText); // 执行同时捕获错误流 Collection<PSObject> results = ps.Invoke(); if (ps.Streams.Error.Count > 0) { StringBuilder errorBuilder = new StringBuilder(); foreach (var error in ps.Streams.Error) { errorBuilder.AppendLine(error.ToString()); } throw new Exception($"PowerShell执行报错:{errorBuilder.ToString()}"); } runspace.Close(); StringBuilder stringBuilder = new StringBuilder(); foreach (PSObject obj in results) { stringBuilder.AppendLine(obj.ToString()); } return stringBuilder.ToString();
原有app.manifest中管理员权限的配置保持不变即可。
方案2:无依赖替代实现(推荐)
不需要调用PowerShell和第三方模块,直接通过C#访问WMI查询BIOS信息,性能更稳定,没有外部依赖:
using System.Management; public static string GetBIOSInfo() { StringBuilder sb = new StringBuilder(); ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_BIOS"); foreach (ManagementObject queryObj in searcher.Get()) { sb.AppendLine($"BIOS版本:{queryObj["Version"]}"); sb.AppendLine($"制造商:{queryObj["Manufacturer"]}"); sb.AppendLine($"发布日期:{ManagementDateTimeConverter.ToDateTime(queryObj["ReleaseDate"].ToString()).ToString("yyyy-MM-dd")}"); sb.AppendLine($"序列号:{queryObj["SerialNumber"]}"); // 可根据需要添加其他字段,比如SMBIOSBIOSVersion、BuildNumber等 } return sb.ToString(); }
使用该方法需要先在项目中添加System.Management程序集的引用。
内容的提问来源于stack exchange,提问作者Nguyễn Nhật Trường
相关产品推荐
相关产品推荐

