PowerShell:如何将COM对象转换为.NET互操作类型?

Mar*_*ica 6 com powershell com-interop powershell-2.0 imapi

如我的问题中所述使用PowerShell创建ISO映像:如何将IStream保存到文件?,在PowerShell中我创建一个IStream对象如下:

$is = (New-Object -ComObject IMAPI2FS.MsftFileSystemImage).CreateResultImage().ImageStream
Run Code Online (Sandbox Code Playgroud)

此对象是(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
Run Code Online (Sandbox Code Playgroud)

但是,此类型的强制转换失败:

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
Run Code Online (Sandbox Code Playgroud)

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

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

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

CB.*_*CB. 7

您可以尝试传入$is(不安全的)c#方法,如object类型,并尝试使用VAR声明为的方法处理它System.Runtime.InteropServices.ComTypes.IStream

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(...)
    }
}
Run Code Online (Sandbox Code Playgroud)

在添加类型后的powershell中:

[MyClass]::MyMethod($is)
Run Code Online (Sandbox Code Playgroud)


x0n*_*x0n 5

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

  • 谢谢!我希望更新您的答案,以包含指向您所描述的功能/行为的更多文档的指针。另外,我的目标是在一些 C# 代码中使用这个“IStream”COM 对象,该代码使用“Add-Type”内联在同一 PowerShell 脚本中,并且 C# 代码需要从“IStream”读取。(我很快就会更新这个问题。)有什么简单的方法可以做到这一点? (2认同)