如何在C#的进程外Runspace中获取PowerShell完整对象?
在C#进程外Runspace中获取PowerShell返回的完整对象
我明白你遇到的问题了——用进程外Runspace跑PowerShell脚本时,返回的复杂类型(比如Get-Process的结果)只能拿到类型名称,没法访问内部成员,但同进程Runspace就没问题。这本质上是因为跨进程通信时,.NET对象不能直接传递,默认的序列化只保留了类型信息,没有序列化对象的实际数据。下面给你两种可行的解决办法:
方法1:使用PowerShell内置序列化机制
PowerShell自带[System.Management.Automation.PSSerializer]类,专门处理PowerShell对象的序列化与反序列化,能完整保留对象的所有成员信息,跨进程传递后再还原回来。
修改后的C#代码示例:
using System; using System.Management.Automation; using System.Management.Automation.Runspaces; class Program { static void Main() { using (var run = RunspaceFactory.CreateOutOfProcessRunspace(null)) { run.Open(); using (PowerShell ps = PowerShell.Create()) { ps.Runspace = run; // 在PowerShell脚本中序列化对象为XML格式 ps.AddScript(@" $processes = Get-Process [System.Management.Automation.PSSerializer]::Serialize($processes) "); // 获取序列化后的XML字符串 var serializedXml = ps.Invoke()[0].ToString(); // 在C#中反序列化回PSObject集合 var processes = (System.Collections.ObjectModel.Collection<PSObject>) PSSerializer.Deserialize(serializedXml); // 现在可以正常访问对象的所有成员了 foreach (var proc in processes) { Console.WriteLine($"进程名: {proc.Properties["ProcessName"].Value}, ID: {proc.Properties["Id"].Value}"); } } } } }
方法2:通过JSON格式传递对象
如果更熟悉JSON,也可以用PowerShell的ConvertTo-Json cmdlet把对象序列化为JSON字符串,再在C#中用JSON库反序列化。注意要指定足够的-Depth参数,避免嵌套对象被截断。
示例代码:
using System; using System.Management.Automation; using System.Management.Automation.Runspaces; using System.Text.Json; class Program { static void Main() { using (var run = RunspaceFactory.CreateOutOfProcessRunspace(null)) { run.Open(); using (PowerShell ps = PowerShell.Create()) { ps.Runspace = run; // 转换为JSON,设置深度确保完整序列化 ps.AddScript("Get-Process | ConvertTo-Json -Depth 10"); var jsonString = ps.Invoke()[0].ToString(); // 反序列化为动态对象(也可以定义对应实体类) var processes = JsonSerializer.Deserialize<dynamic>(jsonString); foreach (var proc in processes) { Console.WriteLine($"进程名: {proc.ProcessName}, ID: {proc.Id}"); } } } } }
为什么同进程Runspace没有这个问题?
因为同进程中,Invoke()返回的对象是直接在当前进程内存中的实例,不需要经过序列化/反序列化步骤,所以能直接访问所有成员。而进程外Runspace是跨进程通信,必须通过序列化把对象转换成可传递的格式,默认的返回结果只是序列化后的“壳”(仅包含类型信息),所以需要我们显式处理序列化过程才能拿到完整数据。
内容的提问来源于stack exchange,提问作者usr1
相关产品推荐
相关产品推荐

