2 Replies Last post: Mar 28, 2008 5:19 PM by Serge Piletsky  
Rob Abbe   2 posts since
Mar 27, 2008
Currently Being Moderated

Mar 27, 2008 11:14 PM

Accessing interfaces

 

I am having a problem accessing a secondary interface from a COM object written in visual basic.  I want to gain access to the secondary interface and wrap an automation around it to invoke the methods.  I am able to gain access to the interface fine, but when I try to invoke methods from the automation object, I get exceptions.  I have attached the project in a zip that also contains the VB dll that contains the objects I am working with.  Below is the class that I am using to interface with the COM objects.

 

 

package test;

 

 

import com.captovation.project1.ITest;

import com.captovation.project1.TestClass;

import com.captovation.project1._ITest;

import com.captovation.project1._TestClass;

 

 

import com.jniwrapper.Function;

import com.jniwrapper.Parameter;

import com.jniwrapper.win32.automation.Automation;

import com.jniwrapper.win32.automation.IDispatch;

import com.jniwrapper.win32.automation.impl.IDispatchImpl;

import com.jniwrapper.win32.automation.types.Variant;

import com.jniwrapper.win32.com.ComFunctions;

import com.jniwrapper.win32.com.IUnknown;

import com.jniwrapper.win32.com.impl.IUnknownImpl;

import com.jniwrapper.win32.com.types.CLSID;

import com.jniwrapper.win32.com.types.ClsCtx;

import com.jniwrapper.win32.com.types.IID;

 

 

import com.jniwrapper.win32.ole.OleFunctions;

 

 

import com.sun.xml.internal.ws.client.dispatch.DispatchImpl;

 

 

public class InterfaceTest {

    public InterfaceTest() {

        // Create an instance of the testclass object.

        CLSID testClassID = CLSID.createFromProgID("Project1.TestClass");

        IUnknown tc = ComFunctions.coCreateInstance(testClassID, null, ClsCtx.INPROC_SERVER);

 

 

        IDispatch idsp = new IDispatchImpl();

        tc.queryInterface(new IID("{EB1B1EF8-0B03-438A-8D4F-85A6DBDDBC09}"), idsp);

        OleFunctions.oleRun(idsp);

 

 

        Automation auto = new Automation(idsp);

        Variant var = auto.invoke("test1");

 

 

    }

 

    public static void main(String[] args) {

        // Initialize COM support.

        ComFunctions.coInitialize();

 

        InterfaceTest it = new InterfaceTest();

 

        // Terminate COM support.

        ComFunctions.coUninitialize();

    }

}

 

 

Attachments:
Serge Piletsky TeamDev Ltd. 670 posts since
Apr 24, 2006
Currently Being Moderated
2. Mar 28, 2008 5:19 PM in response to: Rob Abbe
Re: Accessing interfaces

Hi Rob,

 

I have reviewed your example and made several fixes in order to make it working:

 

package test;
 
import com.captovation.project1.TestClass;
import com.captovation.project1._ITest;
import com.captovation.project1._TestClass;
import com.captovation.project1.impl._ITestImpl;
import com.jniwrapper.win32.automation.Automation;
import com.jniwrapper.win32.automation.IDispatch;
import com.jniwrapper.win32.automation.impl.IDispatchImpl;
import com.jniwrapper.win32.com.ComFunctions;
import com.jniwrapper.win32.com.IUnknown;
import com.jniwrapper.win32.com.impl.IUnknownImpl;
import com.jniwrapper.win32.com.types.CLSID;
import com.jniwrapper.win32.com.types.ClsCtx;
import com.jniwrapper.win32.com.types.IID;
import java.io.IOException;
 
public class InterfaceTest {
 
    public static void release(IUnknown object) {
        if (object != null && !object.isNull()) {
            object.setAutoDelete(false);
            object.release();
        }
    }
 
    public static void testUsingGeneratedStubs() {
        _TestClass testClass = TestClass.create(ClsCtx.INPROC_SERVER);
 
        _ITest test = new _ITestImpl(testClass);
 
        test.test1();
        test.test2();
 
        release(test);
        release(testClass);
    }
 
    public static void testUsignAutomation() throws Exception {
        IUnknown testClass = new IUnknownImpl(TestClass.CLASS_ID, ClsCtx.INPROC_SERVER);
 
        IDispatch test = new IDispatchImpl();
        testClass.queryInterface(new IID(_ITest.INTERFACE_IDENTIFIER), test);
 
        Automation testAutomation = new Automation(test);
        testAutomation.setUseCurrentThread(true);
 
        testAutomation.invoke("test1");
        testAutomation.invoke("test2");
 
        testAutomation.release();
 
        release(test);
        release(testClass);
    }
 
    private static void testIEUsingAutomation() throws IOException {
        final CLSID CLSID_InternetExplorer = new CLSID("{0002DF01-0000-0000-C000-000000000046}");
        IUnknown ieApp = new IUnknownImpl(CLSID_InternetExplorer, ClsCtx.LOCAL_SERVER);
 
        Automation ieAppAutomation = new Automation(ieApp);
        ieAppAutomation.setUseCurrentThread(true);
 
        ieAppAutomation.setProperty("Visible", Boolean.TRUE);
        ieAppAutomation.invoke("Navigate", new Object[]{"www.teamdev.com"});
        System.out.println("Press Enter to terminate IE");
        System.in.read();
        ieAppAutomation.invoke("Quit");
        ieAppAutomation.release();
 
        release(ieApp);
    }
 
    public static void main(String[] args) throws Exception {
        ComFunctions.coInitialize();
 
        System.out.println("Test using integration approach...");
        testUsingGeneratedStubs();
 
        System.out.println("Test Internet Explorer using automation...");
        testIEUsingAutomation();
 
        System.out.println("Test using automation approach...");
        testUsignAutomation();
 
        System.out.println("Done.");
    }
}

 

I have split it to tree different tests. First one invokes the method of you COM interface directly, using the Java COM wrappers that you have provided in InterfaceTest archive. Second test creates and invokes the method of Internet Explorer application using Automation. And finally third one also uses Automation to invoke the methods of ITest COM interface.

 

You will notice that first two tests work just well. But the last one fails with DISP_E_UNKNOWNNAME COM exception. You have not mentioned which COM exception occurs in your case. But I suppose it is the same. It turns out that this exception occurs on attempt to get ID of a COM method using IDispatch.getIDsOfNames() method. Apparently this problem indicates that something is not implemented or implemented incorrectly in your COM object. Because if I invoke those methods using their DispID (which I got from Type Library) then they work fine.

 

Also, I have included the second test just to demonstrate that Automation works with another COM applications.

 

Let me know if you have another questions.

 

-Serge

More Like This

  • Retrieving data ...