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

Ada*_*oll 12 .net c# powershell powershell-sdk

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

例如:

我有一个cmdlet调用WriteObject并推送管道中的ClassXzy集合.当我PowerShell.Invoke从主机端调用时,我检索PSObject带有BaseObject属性的s 集合.铸造BaseObjectClassXyz失败.

有没有办法将每个属性值映射到其对应的原始对象?
我假设PowerShell以某种方式执行此操作,因为您可以将PSObjects 传递给cmdlet并将它们转换为参数类型.但是怎么样?

我花时间用反射器撕裂了PS组件,但还没有真正确定这种魔法是如何发生的.

有任何想法吗?

编辑:我忘记了一个非常重要的细节.在PSObject我正在测试对,因此是一个远程对象BaseObject类型命名Deserialized.ClassXyz.这就是我看到这种奇怪行为的原因.

ste*_*tej 10

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

至于序列化/反序列化

我怀疑是否有可能获得原始对象.我不知道PowerShell使用什么类型的序列化,但是如果你考虑简单的Xml序列化,那么你可以意识到你只能序列化属性而不是其他任何东西.
您无法序列化其方法的bodys.
你不能序列化它的所有事件的订阅者(或者在某些情况下,它可能是可能的,但我不是这样的.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
Run Code Online (Sandbox Code Playgroud)

你会看到,PowerShell

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

我没有看到远程序列化,序列化到clixml(via Export-CliXml)或Receive-Job何时考虑我上面写的内容之间有什么区别,所以我认为在这两种情况下都是不可能的.