【问题标题】:from VBS to WPF via COM通过 COM 从 VBS 到 WPF
【发布时间】:2013-01-28 14:23:00
【问题描述】:

我们有一个讨厌的(或者可能是微不足道的?)问题。

有一个 WPF 控件。它有 2 个接口,主接口和一个用于自动化测试目的的接口。这样定义:

[ComVisible(true)]
[Guid("xxx")]
public interface IXXXXXTest
{
[DispId(1)]
    void Test1(int index);
}

[ComVisible(true)]
public interface IXXXXX
{
    void Main1(index);
}

[ComVisible(true)]
[Guid("xxx")]
ClassInterface(ClassInterfaceType.None)]
public partial class XXXXX_WPF_CONTROL : UserControl,
                         IXXXXX,
                         IXXXXXTest
{
     ...
}

现在我们正在尝试从 VBS 访问它。 试试 1)

Set Ctrl = GetControl(...)  <---- this is ok
Ctrl.Test1(0)  <---- Object doesn't support this property or method: 'Ctrl.Test1'

Set Ctrl = GetControl(...)  <---- this is ok
Ctrl.Main1(0)  <---- this is ok

所以它适用于“主”界面,但适用于测试界面。 这似乎没问题(?),因为据我所知,如果没有 IDispatchEx,VBS 只能通过 IDispatch 到达“主”界面。所以我给IXXXXX加了一个属性来获取测试接口。

[ComVisible(true)]
public interface IXXXXX
{
    void Main1(index);
    IXXXXXTest Test { get;}
}
....
public IXXXXXTest Test
{
    get {   return this as IXXXXXTest;  }
}

太好了,现在我可以通过“主”界面访问这个 IXXXXTest 界面。 试试 2)

VBS:

Set Ctrl = GetControl(...)  <---- this is ok
Set CtrlTest = Ctrl.Test  <----- this is ok
CtrlTest.Test1(0)    <---- Object doesn't support this property or method: 'CtrlTest.Test1'

:(

请注意,对于我们的其他 .NET 控件,“Try1”可以正常工作,没有任何技巧!

所以可能是由于 WPF 的不同吗? 另外,改变

ClassInterface(ClassInterfaceType.None)]

进入其他任何东西(AutoDispatch / AutoDual),或者离开它会使 WPF 控件不可用。

除此之外,这篇文章也应该是这样的:Is it possible to package WPF window as COM Object

您知道可能是什么问题吗? 非常感谢!

【问题讨论】:

    标签: wpf com interface vbscript


    【解决方案1】:

    脚本语言只能使用类的默认接口。你有不止一个,所以至少其中一个将不可用。如果与其他声明冲突,方法名称可能会被重命名。我假设你在你的问题中混淆了真实姓名,很难从你发布的内容中诊断出这样的重命名。

    最好的办法是在您的接口类型上临时应用 [InterfaceType(ComInterfaceType.InterfaceIsDual)] 属性。它允许您使用 Tlbexp.exe 生成类型库,然后您可以使用 OleView.exe 实用程序 File + View Typelib 命令查看该库。您将看到方法的确切名称,并且您将看到哪个接口是 coclass 上的 [默认] 接口。从那里您应该可以轻松地修改您的声明,以便它们可以在脚本语言中工作。

    【讨论】:

    • 感谢您的回复,我不是要混淆,而是要让它更清楚:) 我检查了 Tlb,这就是我的想法:IXXXX 是 [默认] 接口。但是,您可以访问它的“Test”属性,它将对象作为 IXXXXTest 接口返回。这可以从 VBS 访问。所以(理论上)我在 VBS 中有一个到这个对象的 IXXXTest 接口。但是在接口上调用方法失败,因为“对象不支持......”虽然这个 IXXXTest 接口(在 TLB 中检查)有那个 Test1() 方法
    • 此外,我们有一个基本的.NET控件,它还实现了更多的接口,我们可以直接从VBS上的任何接口访问任何功能,而不仅仅是[default[.奇怪的!仅此 WPF 控件失败,即使通过导出的非默认接口...
    • 汉斯,你给出了解决方案的线索。
    • 我有解决方案:您需要一个测试器类,该测试器类将要测试的对象作为成员,并实现测试器接口。然后委托给主类。在我的示例中:class XXXXTester : IXXXXTest { XXXX _xxxx; public XXXXTester(XXXX x) { _xxxx = x; } //here comes IXXXXTest members public Test1() { ... } } 在我测试的类 XXXX public IXXXXXTest Test { get { return new (XXXXTester(this)); } } 中,它可以工作。汉斯,你给出了解决方案的线索,所以我把答案给了你。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-18
    • 2013-02-10
    • 1970-01-01
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    • 2019-10-20
    相关资源
    最近更新 更多