Runtime error 429 in VBA, but class is registered

3.4k views Asked by At

I'm trying to recreate a program that uses javascript to open a connection to a PLC and then display all sorts of information on a web page. I'd rather have it in a form in MS Access for various reasons, and have spent forever trying to find the right dll to use (Jet32X.dll, if anyone is curious). I finally tracked the CLSID called out in the javascript back to a registered class for the PLC, and I'm trying to create that object in VB code. It won't get any further than the Dim As New line, however, throwing runtime error 429: "Active X Component Cannot Create Object." Really wish I had some more information about why.
I know the class is registered, since that's how I found it in the first place. I know the DLL file isn't corrupted, since the program runs fine from the JS version. I have a sneaky suspicion that there's some sort of incompatibility going on here, since the PLC and supporting software is pretty old, and I'm working in Microsoft Access 2013 (and its associated VBA). I can't really think of a good way to verify this, however. Does anyone have any other ideas? Could anything else be causing this problem?

2

There are 2 answers

0
NickGlowsinDark On BEST ANSWER

Figured it out; in case anyone else runs into this sort of issue:
32bit COM dlls will not run in 64bit applications. If you don't want to go back and reinstall 32bit versions of whichever application you're using, one of the easiest workarounds is using dllhost.exe as a surrogate. You can read a little about it here, but I found this tutorial easier to follow.

0
Jacopo Tedeschi On

I send a new reply just to recap the information and avoid anyone that stumbles in the same problem again after me wasting precious time. All the steps involved assume that you already correctly registered the dll you are trying to use.

How to make a 32bit COM Dll work in a 64bit application

The "easy" solutions involve using the Dll Surrogate method, which runs dllhost.exe and as an intermediary process in 64bit to expose the underlying 32bit dll. When done correctly this works seamlessly without any special measure needing to be taken in neither in the 32bit dll nor in the 64bit application.

There are two main approaches to this:

Using Oleview.exe (i.e. using a GUI)

Oleview can be obtained downloading the Window 10 SDK. In order to use Oleview it you have to:

  1. Download the Window 10 SDK at the following link: https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
  2. Go to C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x86 to find the 32bit version of oleview.exe
  3. ONLY THE FIRST TIME: run it as administrator to avoid see the message related to the impossibility to load iviewer.dll
  4. In the left pane, Object Classes -> All Objects and find your dll name.

Object Classes -> All Objects

  1. WARNING: you may find many entries for your dll. In particular each class has got its own entry such as YourProjectName.YourClassName
  2. In the right pane, go to Implementation -> Inproc Server, and tick Use Surrogate Process. Leave the Path to Custom Surrogate empty to use the system default surrogate, that is dllhost.exe.

Use Surrogate Process

  1. You can check the procedure went correctly by returning to the Registry tab, always in the right pane of the Oleviewer and make sure that now under CLSID = {yourAppIdHere} [DllSurrogate] = is listed among the entries.

enter image description here

Edit manually the Windows Registry

The Oleview method is recommended, but the manual method may be ok if you need to do this only once. The tutorial that NickGlowsinDark mentions was moved to https://techtalk.gfi.com/32bit-object-64bit-environment/ . In order to avoid problems in the future with the page going offline I copy and paste here the most important steps involved. All credit goes to Emmanuel Carabott that is the original author of the tutorial, I added the first two steps in order to facilitate you in the process.

Open the Registry Editor (Windows+R -> regedit), and follow the following steps:

  • You first need to find your dll GUIDs. You will probably have many GUIDs, one for each of the classes that your dll exports. I find it's easier to find the GUIDs if you go to HKEY_CLASSES_ROOT\YourProjectName.YouClassName. It is the (Default) String Value you find under the Clsid key.

HKEY_CLASSES_ROOT\YourProjectName.YouClassName

  • I recommend you find all the GUIDs first and make a note of them in order to have an easier time with the steps after this one.

Then, as Emmanuel Carabott kindly explains in his article, you have to do the following for each of the GUIDs you found:

  • Locate your COM object GUID under the HKey_Classes_Root\Wow6432Node\CLSID\[GUID]
  • Once located add a new REG_SZ (string) Value. Name should be AppID and data should be the same COM object GUID you have just searched for.

AppID

  • Add a new key under HKey_Classes_Root\Wow6432Node\AppID\ The new key should be called the same as the com object GUID
  • Under the new key you just added, add a new REG_SZ (string) Value, and call it DllSurrogate. Leave the value empty.

DllSurrogate

  • Create a new Key under HKey_Local_Machine\Software\Classes\AppID\ Again the new key should be called the same as the COM object’s GUID. No values are necessary to be added under this key.

HKey_Local_Machine\Software\Classes\AppID\

That’s it, your COM Object should now be accessible from a 64bit environment and can be used like a regular COM Object.