Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 自定义PowerShell主机并将PSObject转换回基类型_C#_.net_Powershell_Powershell Sdk - Fatal编程技术网

C# 自定义PowerShell主机并将PSObject转换回基类型

C# 自定义PowerShell主机并将PSObject转换回基类型,c#,.net,powershell,powershell-sdk,C#,.net,Powershell,Powershell Sdk,托管PowerShell运行时时,是否可以将PSObject转换回其原始类型 例如: 我有一个cmdlet,它调用WriteObject,并在管道中推送ClassXzy的集合。当我从事物的主机端调用PowerShell.Invoke时,我使用BaseObject属性检索PSObjects的集合。将BaseObject强制转换为ClassXyz失败 是否有办法将每个属性值映射到其对应的原始对象? 我假设PowerShell以某种方式做到这一点,因为您可以将PSObjects传递给cmdlet,并将

托管PowerShell运行时时,是否可以将
PSObject
转换回其原始类型

例如:

我有一个cmdlet,它调用
WriteObject
,并在管道中推送ClassXzy的集合。当我从事物的主机端调用
PowerShell.Invoke
时,我使用
BaseObject
属性检索
PSObject
s的集合。将
BaseObject
强制转换为
ClassXyz
失败

是否有办法将每个属性值映射到其对应的原始对象?
我假设PowerShell以某种方式做到这一点,因为您可以将
PSObject
s传递给cmdlet,并将它们转换为参数类型。但是怎么做呢

我花了很长时间研究带有反射器的PS组件,但还没有真正弄清楚这种魔法是如何发生的

有什么想法吗


编辑:我忘记了一个非常重要的细节。我测试的
PSObject
是一个远程对象,因此
BaseObject
类型被命名为
反序列化的.ClassXyz
。这就是为什么我看到如此奇怪的行为

您可以访问
PSObject
上的
BaseObject
属性(该属性遍历每个PSObject,直到它到达实际的基本对象),或者访问仅捕获链中下一个对象的
ImmediateBaseObject

在您提到反序列化过程之前,Keith已经回答了您的问题

至于序列化/反序列化 我怀疑是否有可能得到原物。我不知道什么类型的序列化PuthSek使用,但是如果你考虑简单的XML序列化,那么你可以意识到你只能序列化属性而不需要其他。
无法序列化其方法的正文。
您无法序列化所有它的事件订阅者(或者在某些情况下可能是这样,但我不是这样的.NET专家)。
而且由于类型(如我的示例中)可能不可用(例如,程序集仅存在于远程计算机上),因此需要传输所有类型信息

它不仅与类型有关,还与对象实现的所有继承层次结构和接口有关。它们也会以某种方式被序列化

试试这个例子:

$deserialized = Start-Job {
    Add-Type -TypeDefinition @"
    public class Parent {
        public override string ToString() { return "overriden parent"; }
        public int IntParent { get { return 1; } }
    }
    public class TestClass : Parent
    {
        public string GString() { return "this is a test string"; }
        public override string ToString() { return "overriden tostring" + System.DateTime.Now.ToString(); }
        public int IntProp { get { return 3451; } }
    }
"@
    New-Object TestClass
} | Wait-Job | Receive-Job
$deserialized.ToString()
$deserialized | gm -for
你会看到,那是个超级地狱

  • 展平继承层次结构
  • “仅实现”属性
  • 因为它知道
    ToString()
    的值,所以它还可以添加方法的结果。但是正如您所看到的,从
    ToString()
    返回的信息不再反映日期更改-它是冻结值

考虑到我上面所写的内容,我看不出远程处理的序列化、clixml的序列化(通过导出clixml)或接收作业时的序列化有什么区别,所以我认为在这两种情况下都是不可能的。

您可以做上面所描述的事情,然而,一旦PSRemoting开始发挥作用,这些方法都将崩溃,因为您将访问代理对象。使用PSMembers和psproperty是最佳实践

我忘了一些非常重要的东西。PSObject来自远程操作。有关更多详细信息,请参阅我更新的问题。您的答案实际上适用于本地操作。PowerShell远程处理在下面使用WSMan/SOAP,因此它不会“远程”活动对象。作为“反序列化。*”对象返回的只是一个属性包,与原始对象没有连接。谢谢。远程因素彻底改变了这个问题!是的,我思考过程中的缺陷是我完全忘记了远程处理部分!在管道的另一侧不可能有活动对象,这是有道理的。谢谢你的好例子。