4

我在 C# 中有以下代码,我尝试将其移植到 PowerShell。但我不知道如何移植这个演员:

((_ISkypeEvents_Event)skype).CallStatus += CallStatusHandler;

如果我只是在我的 PowerShell 控制台中键入 [Skype4COM.ISkypeEvents_Event],我会得到:

找不到类型 [Skype4COM.ISkypeEvents_Event]:确保已加载包含此类型的程序集。

但是,我可以获得 $skype 对象的所有成员:

$skype = New-Object -ComObject Skype4COM.Skype

以下行不起作用:

$skypeevent = [Skype4COM._ISkypeEvents_Event]$skype

如果我尝试直接在 $skype 对象上调用该方法,如下所示:

$skype.add_CallStatus({ write-host "yay" })

...它(如预期的那样)告诉我:

方法调用失败,因为 [System.__ComObject#{b1878bfe-53d3-402e-8c86-190b19af70d5}] 不包含名为“add_CallStatus”的方法。

我试图创建一个 COM 包装器,但它仍然无法获取 COM 接口的类型......

有任何想法吗?非常感谢!

4

1 回答 1

5

PowerShell 使用自己的后期绑定“COM 适配器”对 COM 对象进行特殊处理,以便将成员公开给调用者(以及Get-Member cmdlet)。不幸的是,如果找不到关联的类型库,这有时会失败,这通常发生在实例实际上是通过透明代理类型呈现的远程 COM 对象时。

这种 COM 改编的另一个副作用是间接阻止您使用这些类型的强制转换来访问成员。PowerShell 通常公开互操作程序集的(动态创建或 PIA)CoClass 类,其中包括所有接口的成员。事实上,接口的这种限制不仅仅针对 COM 对象:PowerShell 中的“.NET 适配器”也不处理普通的旧 .NET 接口。老实说,这是 99% 案例的首选行为。PowerShell 是一种动态语言,并且始终会在运行时公开引用的真实类型。任何转换为​​接口的尝试都将被忽略。

当您在 C# 中显式实现接口时,这会导致更多问题。PowerShell 根本看不到它们!我写了一篇关于使用 v2.0 模块代理显式接口成员的技术的博客。您可以针对 COM 接口尝试它,但我不确定它是否会起作用。

于 2009-10-28T21:35:38.453 回答