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

8

如我在问题描述中所述使用PowerShell创建ISO镜像:如何将IStream保存到文件?,在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对象。这是可能的吗?如果不行,我有哪些替代方案?
2个回答

8
您可以尝试将$is作为object类型传递给(不安全的)c#方法,并尝试使用声明为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 中使用 add-type 后:
[MyClass]::MyMethod($is)

1
没错!之前我有一个 MyMethod(IStream i),然后 PowerShell 尝试将其转换为 IStream 时失败了。按照您的建议,让 .NET/CLR 来进行转换就可以了。奖金即将到账。 - MarnixKlooster ReinstateMonica

5

你无法让这个工作。PowerShell使用透明的“com适配器”层来阻止这种情况发生,但是在脚本中启用了延迟绑定。对于大多数情况来说,这是一件好事,但不是在你的情况下。


2
谢谢!我希望您能更新您的答案,包括一些更多关于您所描述的功能/行为的文档指针。此外,我的目标是在同一 PowerShell 脚本中使用 Add-Type 内联的一些 C# 代码来使用这个 IStream COM 对象,并且这些 C# 代码需要从 IStream 中读取。(我很快会更新这个问题。)有什么简单的方法可以做到这一点? - MarnixKlooster ReinstateMonica
1
请查看我的个人资料 - 我是一名五年的PowerShell微软MVP,直接与PowerShell团队联系。我知道;) - x0n

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接