2012-01-27 75 views
4

正如在我的问题Create ISO image using PowerShell: how to save IStream to file?所描述的,在PowerShell中创建一个对象IStream如下:PowerShell:如何将COM对象转换为.NET互操作类型?

$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#代码,它会成为System.Runtime.InteropServices.ComTypes.IStream类型的.NET对象(使用Add-Type相同PowerShell脚本的一部分)。那可能吗?如果没有,我有什么替代方案?

回答

5

你可以尝试通过$is在(不安全的)C#方法就像一个object型,并尝试与声明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(...) 
    } 
} 

在PowerShell中加载项类型后VAR来处理它:

[MyClass]::MyMethod($is) 
+0

而且工作!以前我有'MyMethod(IStream i)',然后PowerShell做到了转换为'IStream',并失败。正如你所建议的那样,让.NET/CLR来完成转换。赏金来了你的方式。 – 2012-03-22 10:46:13

+0

乐意帮忙!有同样的问题,并尝试这种方式来处理.net中的comobject – 2012-03-22 10:50:25

3

你不能使这项工作。 PowerShell使用一个透明的“com适配器”层来防止这种情况发挥作用,但是可以在脚本中启用后期绑定。在大多数情况下,这是一件好事,但不在你的情况。

+0

谢谢!我希望你的答案更新包括一个指向你正在描述的特性/行为的更多文档的指针。另外,我的目标是在一些C#代码中使用这个'IStream' COM对象,这些代码使用'Add-Type'在同一个PowerShell脚本中内联,并且C#代码需要从'IStream'中读取。 (我会尽快更新这个问题。)什么是简单的方法来做到这一点? – 2012-01-27 19:41:20

+1

检查我的个人资料 - 我是一个5年PowerShell微软MVP与直接访问PowerShell团队。我知道;) – x0n 2012-01-27 22:34:46

相关问题