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

标签 c# .net powershell powershell-sdk

托管 PowerShell 运行时时,是否可以通过某种方式将 PSObject 转换回其原始类型?

例如:

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

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

我花了很多时间使用 Reflector 研究 PS 组件,但还没有真正弄清楚这种魔法是如何发生的。

有什么想法吗?

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

最佳答案

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

至于序列化/反序列化

我怀疑是否有可能获得原始对象。我不知道 PowerShell 使用什么类型的序列化,但如果您考虑简单的 Xml 序列化,您就会意识到您可以序列化仅属性,而不能序列化其他任何内容。
你不能序列化它的方法体。
你不能序列化所有它的事件订阅者(或者在某些情况下它是可能的,但我不是这样的 .NET 专家)。
并且由于类型(如我的示例)可能不可用(例如,程序集仅存在于远程计算机上),因此需要传输所有类型信息。

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

试试这个例子:

$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

你会看到,PowerShell

  • 扁平化继承层次结构。
  • 仅“实现”属性
  • 并且因为它知道 ToString() 的值,所以它也可以添加该方法的结果。但是正如您所见,从 ToString() 返回的信息不再反射(reflect)日期更改 - 它是卡住值。

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

关于c# - 自定义 PowerShell 主机并将 PSObject 转换回基本类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2330659/

相关文章:

c# - 调用堆栈不说 "where you came from",而是 "where you are going next"?

c# - 如何使用 .Net Framework 3.5 或 4.5,具体取决于哪个版本可用

.net - 使用反射创建对象 : Activator. CreateInstance 或 Inovking 构造函数 C#

asp.net - 如何使用 localDB 将 ASP.NET MVC 4 应用程序部署到 Windows 7 上的本地 IIS?

.net - Entity Framework 没有外键加入

powershell - PowerShell-不执行Lambda函数

Powershell脚本来定位特定文件/文件名?

c# - 阅读下面的 xml 显示 c# 中的错误

c# - 如何在不影响其子项的情况下将属性应用于控件

powershell - 如何使用PowerShell或VBScript获取正在运行的应用程序的列表