4

I have the following configuration:

1) Windows 10 64-bit

2) An application that has only a 32-bit version and is available through COM.

I access the .dll file of the 32-bit application using the tlbimb.jar to generate the interfaces needed and I succeed.

Scenario 1: I try to access the 32-bit application using the Java 8 32-bit installation. I can invoke the methods through COM succesfully without any problem.

Scenario 2: I try to access the 32-bit application using a Java 8 64-bit installation. I get an error message:

Exception in thread "main" com4j.ExecutionException: com4j.ComException: 80040154 CoCreateInstance failed : Class not registered : .\com4j.cpp:153

I searched for the exceptin on Stackoverflow/Google and I have done the following:

1) Registered the application's dll using both Sys64WOW/regsvr32.exe and the System32/regsvr32.exe

2) Registered the com4j dll (both 32 and 64 bit) using both Sys64WOW/regsvr32.exe and the System32/regsvr32.exe

3) Copied the dlls in the Sys64WOW and System32 folders.

I have done all the above separatelly, checking all the possible combinations. The afortementioned error using 64-bit Java still exists.

I have tried using another bridge (Jacob). On 32-bit Java it succeeds, on 64-bit Java it fails.

I have a question for someone that might knows: Is there any way to connect an app that, as far as I can tell, offers only a Win32 COM dll[1], using any of the available Java/COM bridges and Java 64bit? Or simply 32-bit COM + 64-bit Java are not connectable?

[1]: I checked the OLE/COM Viewer and under the Type Library there's is only one entry "0 Win32 = , so I implied that this means there's no Win64 COM dll, right?

Thanos
  • 3,627
  • 3
  • 24
  • 35

1 Answers1

4

This won't work because the bitness of your client process and COM DLL don't match. When trying to create a new instance, CoCreateInstance tries to find related class information in the 64-bit hive of the registry. This fails because its actually located in the 32-bit hive, where you registered the DLL.

To remedy this, you have the option of using a surrogate process, which allows your CoClass to be instantiated in a distinct native process. Your client can then communicate with the surrogate via IPC (see here for further info).

As a quick start, you can mark your CoClass as a candidate for the default dllhost.exe surrogate process: OLE/COM Object Viewer (x86) as Admin > All Objects > [Your CoClass] > Implementation > Use Surrogate Process (leave path empty).

If you intend to distribute your application, you may place this information in a REG script or import your DLL into a COM+ server application.

Aurora
  • 1,334
  • 8
  • 21
  • Thanks for the reply. I did this "As a quick start, you can mark your CoClass as a candidate for the default dllhost.exe surrogate process: OLE/COM Object Viewer (x86) > All Objects > [Your CoClass] > Implementation > Use Surrogate Process (leave path empty)." but still the same error. I tick the Use Surrogate Process box but when I navigate to another CoClass and then back to my CoClass the box is unticked. Is there any chance that my choice is not saved? – Thanos Apr 01 '17 at 07:49
  • Did you run oleview as admin? It needs the respective privileges to write to the registry. You can verify that the settings were saved correctly by switching to the Registry tab of your CoClass. There should be a [DllSurrogate] entry visible below the AppID node. – Aurora Apr 01 '17 at 08:40
  • Ok, I had to run as admin. Now it is saved and it works from the 64-bit Java. Thank you very much. Your help is really appreciated. – Thanos Apr 01 '17 at 08:51
  • Can you add a sample script or explain how to create one? – orirab Mar 09 '21 at 12:03
  • Take a look at [this](https://stackoverflow.com/a/8900593) answer for an example. – Aurora Mar 15 '21 at 16:55