0

we have a nasty (or maybe a trivial?) issue.

There is a WPF control. It has 2 interfaces, the main and one for automated testing purpose. Defined this way:

[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
{
     ...
}

Now we are trying to reach it from VBS. Try 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

So it works fine for the "main" interface but for the test interface. This seems ok(?), because as far as I know VBS reaches the "main" interface only via IDispatch if there is no IDispatchEx. So I added a property to the IXXXXX to get the test interface.

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

Great, so now I can reach this IXXXXTest interface via the "main" interface. Try 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'

:(

Note that, for an other .NET control of us the "Try1" works, without any trick!

So probably due to the WPF something different? Also, changing the

ClassInterface(ClassInterfaceType.None)]

into anything else (AutoDispatch / AutoDual), or leaving it makes the WPF control unusable.

Besides that this is also how it should be by this article: Is it possible to package WPF window as COM Object

Do you have any idea what could be the problem? Thank much in advance!

1 Answer 1

1

Scripting languages can only use the default interface on a class. You've got more than one so at least one of them will not be usable. And method names may be renamed if they conflict with other declarations. I'd assume you obfuscated the real names in your question so hard to diagnose such a renaming happening from what you posted.

Best thing to do is to temporarily apply the [InterfaceType(ComInterfaceType.InterfaceIsDual)] attribute on your interface types. Which allows you to generate a type library with Tlbexp.exe which you can then view with the OleView.exe utility, File + View Typelib command. You'll see the exact names of the methods and you'll see which interface is the [default] one on the coclass. From there you should have little trouble modifying your declarations so they'll work in a scripting language.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks your reply, I did not mean to obfuscate but to make it more clear :) I checked the Tlb, and that's what I thought: the IXXXX is the [default] interface. However you can reach it's "Test" property, which returns the objects as IXXXXTest interface. And this is accessible from the VBS. So (in theory) I have an IXXXTest interface to this objects in the VBS. However calling a method on the interface fails as "Object doesn't support..." While this IXXXTest interface (checked in the TLB) HAS that Test1() method
Moreover, we have a basic .NET control, which also implements more interfaces, and we can reach ANY function from any interface on this from VBS directly, not only the ones from the [default[. Strange! It only fails for this WPF control, even via the exported non-default-interface...
Hans, you gave a clue for the solution.
I have the solution: you need a tester class which has the object to test as a member, and implements the tester interface. Then delegates to the main class. In my example: class XXXXTester : IXXXXTest { XXXX _xxxx; public XXXXTester(XXXX x) { _xxxx = x; } //here comes IXXXXTest members public Test1() { ... } } And in the class XXXX public IXXXXXTest Test { get { return new (XXXXTester(this)); } } I tested, it works. Hans, you gave a clue for the solution, so I gave the answer to you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.