【问题标题】:PowerShell: how to convert a COM object to an .NET interop type?PowerShell:如何将 COM 对象转换为 .NET 互操作类型?
【发布时间】:2012-01-27 16:20:02
【问题描述】:

正如我的问题 Create ISO image using PowerShell: how to save IStream to file? 中所述,在 PowerShell 中我创建了一个 IStream 对象,如下所示:

$is = (New-Object -ComObject IMAPI2FS.MsftFileSystemImage).CreateResultImage().ImageStream

此对象的 (PowerShell) 类型为 System.__ComObject。不知何故,PowerShell 知道它是一个IStream

PS C:\> $is -is [System.Runtime.InteropServices.ComTypes.IConnectionPoint]
False
PS C:\> $is -is [System.Runtime.InteropServices.ComTypes.IStream]
True

但是,转换为这种类型失败:

PS C:\> [System.Runtime.InteropServices.ComTypes.IStream] $is
Cannot convert the "System.__ComObject" value of type "System.__ComObject" to type "System.Runtime.InteropServices.ComT
ypes.IStream".
At line:1 char:54
+ [System.Runtime.InteropServices.ComTypes.IStream] $is <<<<
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException

如何在不使用 C# 代码的情况下进行这种转换?

更新:显然,正如 x0n 的回答所说,这种转换无法正常工作。

现在,我的目标是将这个 IStream COM 对象传递给一些 C# 代码(使用 Add-Type 的同一 PowerShell 脚本的一部分),在那里它将成为 System.Runtime.InteropServices.ComTypes.IStream 类型的 .NET 对象。那可能吗?如果没有,我有什么选择?

【问题讨论】:

    标签: powershell com powershell-2.0 com-interop


    【解决方案1】:

    您可以尝试在(不安全的)c# 方法中传递$is,例如objecttype,并尝试使用声明为System.Runtime.InteropServices.ComTypes.IStreamVAR 处理它

    public unsafe static class MyClass
    {
        public static void MyMethod(object Stream) 
        {
           var i = Stream as System.Runtime.InteropServices.ComTypes.IStream; 
    
        //do something with i like i.read(...) and i.write(...)
        }
    }
    

    在powershell中添加类型后:

    [MyClass]::MyMethod($is)
    

    【讨论】:

    • 这行得通!以前我有MyMethod(IStream i),然后PowerShell 转换为IStream,但失败了。正如您所建议的那样,让 .NET/CLR 进行转换是可行的。赏金即将到来。
    【解决方案2】:

    你无法做到这一点。 PowerShell 使用透明的“com 适配器”层来阻止它工作,但在脚本中启用后期绑定。在大多数情况下,这是一件好事,但不是你的。

    【讨论】:

    • 谢谢!感谢您更新您的答案,以包含指向您所描述的功能/行为的更多文档的指针。另外,我的目标是在一些 C# 代码中使用这个 IStream COM 对象,这些代码使用 Add-Type 内联在同一个 PowerShell 脚本中,并且 C# 代码需要从 IStream 中读取。 (我会尽快更新这个问题。)有什么简单的方法可以做到这一点?
    • 查看我的个人资料 - 我是 5 年的 powershell microsoft mvp,可以直接访问 powershell 团队。我知道;)
    猜你喜欢
    • 2011-10-02
    • 2010-12-07
    • 2019-03-02
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    相关资源
    最近更新 更多