C#.NET Framework中如何将PowerShell脚本转为PowerShell对象方法调用
C# 调用 PowerShell 对象实现进程CPU使用率采集的完整实现
前置条件
- 项目已正确引用
System.Management.Automation.dll - 代码文件已引入对应命名空间:
using System.Management.Automation;
实现方案1:逻辑拆分到C#原生处理(更灵活)
该方案将原PowerShell的计算、写入逻辑迁移到C#代码中,方便后续扩展参数配置、结果二次处理等需求:
using System.Management.Automation; using System.IO; public void GetProcessCpuUsage() { // 可自定义配置参数 string targetProcessName = "Notepad"; string outputFilePath = @"D:\FolderName\data.txt"; // 初始化PowerShell对象,用using自动释放资源 using (PowerShell powerShell = PowerShell.Create()) { // 1. 获取逻辑处理器核心数 powerShell.AddCommand("Get-WmiObject").AddArgument("Win32_ComputerSystem"); var computerInfoResult = powerShell.Invoke(); int cpuCoreCount = (int)computerInfoResult.First().Properties["NumberOfLogicalProcessors"].Value; // 清空已有命令,避免后续执行冲突 powerShell.Commands.Clear(); // 2. 获取目标进程的CPU性能计数器样本 string counterPath = $@"\Process({targetProcessName}*)\% Processor Time"; powerShell.AddCommand("Get-Counter").AddArgument(counterPath); var counterResult = powerShell.Invoke(); dynamic counterSamples = counterResult.First().Properties["CounterSamples"].Value; powerShell.Commands.Clear(); // 3. 计算CPU占比并追加写入文件 using (StreamWriter writer = File.AppendText(outputFilePath)) { foreach (var sample in counterSamples) { decimal cpuUsage = Math.Round((decimal)sample.CookedValue / cpuCoreCount, 2); writer.WriteLine($"CPU %: {cpuUsage}"); } } } }
实现方案2:直接复用原有PS1脚本逻辑(迁移成本最低)
如果不需要调整原有逻辑,可直接将PS1脚本作为脚本块传入PowerShell对象执行,完全匹配原脚本行为:
using System.Management.Automation; public void RunOriginalPsLogic() { using (PowerShell powerShell = PowerShell.Create()) { // 直接填入原PS1脚本内容,注意特殊字符转义 string psScript = @" $ProcessName = 'Notepad' $Path = 'D:\FolderName\data.txt' $CpuCores = (Get-WMIObject Win32_ComputerSystem).NumberOfLogicalProcessors $Samples = (Get-Counter ""\Process($Processname*)\% Processor Time"").CounterSamples $Samples | Select @{Name=""CPU %"";Expression={[Decimal]::Round(($_.CookedValue / $CpuCores), 2)}} | Out-File -FilePath $Path -Append "; powerShell.AddScript(psScript); // 执行脚本,无返回值需求可直接调用 powerShell.Invoke(); // 可选:检查执行错误 if (powerShell.HadErrors) { foreach (var error in powerShell.Streams.Error) { // 处理错误逻辑 System.Diagnostics.Debug.WriteLine(error.ToString()); } } } }
注意事项
- 运行程序的账号需要有WMI查询和性能计数器的访问权限,否则会出现执行报错
- 系统为64位时,需确保项目的平台目标与PowerShell的位数匹配,避免出现性能计数器找不到的问题
- 如果目标进程存在多个同名实例,会依次输出每个实例的CPU使用率,和原脚本行为一致
内容的提问来源于stack exchange,提问作者Guillermo Soto
相关产品推荐
相关产品推荐

