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?
- 337
- 1
- 6
- 17
-
Have you tried `Dim obj as Object` and then `Set obj = CreateObject("...")`. Failing that, it would be useful to post some actual code. – Tim Williams Dec 02 '13 at 19:40
-
Further to the comment from @TimWilliams ... If you know the CLSID of the component then you can try something like `Set obj = CreateObject("new:{0CF774D0-F077-11D1-B1BC-00C04F86C324}")`. – Gord Thompson Dec 02 '13 at 20:12
-
Private Sub Form_Load() Dim plc As JET32XLib.JVJet32X Set plc = CreateObject("new:{0D9DCFA5-9A1D-11D6-9E19-0050BA6EEA16}") – NickGlowsinDark Dec 03 '13 at 00:17
-
Woops, forgot to hold shift while pressing enter. 'Private Sub Form_Load() Dim plc As JET32XLib.JVJet32X Set plc = CreateObject("new:{0D9DCFA5-9A1D-11D6-9E19-0050BA6EEA16}") ' But yeah, hadn't tried the CreateObject thing before, but it still doesn't work. It's not one of those "you can't do that inside a subroutine" things, is it? I can't possibly see how it could. – NickGlowsinDark Dec 03 '13 at 00:26
-
1@NickGlowsinDark is your Excel 32 or 64 bit? Old `*.dll`'s very often do not support 64bit systems – Dec 03 '13 at 08:17
-
Does it make any difference if you `Dim plc As Object` instead of using `Dim plc As JET32XLib.JVJet32X`? – Gord Thompson Dec 03 '13 at 09:41
-
Tried it as 'Object' just now, no change. @mehow, it's 64 bit, which is a good point. It took me forever to get all the random Microsoft products on my computer to interact with each other, and I resisted changing over to 64 bit as long as I could, but in the end that was the only way I could do it. There's pretty much no chance that the manufacturer has released a 64 bit dll for those old PLCs; do you know of anything I could try to see if that's the problem without uninstalling everything and trying to reinstall the 32 bit stuff (MSOffice 2013 won't let you have both at the same time)? – NickGlowsinDark Dec 03 '13 at 13:03
-
1You could create a very simple VBScript that uses `CreateObject()` and then run it as 32-bit from the command line using `C:\Windows\SysWOW64\cscript.exe`. – Gord Thompson Dec 03 '13 at 13:17
-
@NickGlowsinDark see [this](http://office.microsoft.com/en-us/help/why-cant-i-install-both-the-32-bit-and-64-bit-versions-of-office-2013-HA103523746.aspx) but I haven't done it like that so I can't guarantee it would work. The possible problem is the 32/64bit compatibility. Any way you could add references to the *.dll in your own Eg. C# library and then compile it for 64 bit machine? If you want to get a better idea see [one of my answers](http://stackoverflow.com/questions/19927852/vba-get-excel-filedialogopen-to-point-to-my-computer-by-default/19931128#19931128). instead of forms refer dll – Dec 03 '13 at 13:18
-
2GordThompson, that's a good idea, but I just figured it out following some other people's angry posts on microsoft forums. @mehow, you were totally right, it was the 32bit COM in a 64bit environment. I managed to use dllhost to act as a go-between using this tutorial: [link](http://www.gfi.com/blog/32bit-object-64bit-environment/) Worked like a charm! Appreciate everyone's help in leading me in the right direction. – NickGlowsinDark Dec 03 '13 at 13:35
2 Answers
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.
- 337
- 1
- 6
- 17
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:
- Download the Window 10 SDK at the following link: https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
- Go to
C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x86to find the 32bit version of oleview.exe - ONLY THE FIRST TIME: run it as administrator to avoid see the message related to the impossibility to load iviewer.dll
- In the left pane,
Object Classes -> All Objectsand find your dll name.
- WARNING: you may find many entries for your dll. In particular each class has got its own entry such as YourProjectName.YourClassName
- In the right pane, go to
Implementation -> Inproc Server, and tickUse Surrogate Process. Leave thePath to Custom Surrogateempty to use the system default surrogate, that is dllhost.exe.
- You can check the procedure went correctly by returning to the
Registrytab, always in the right pane of the Oleviewer and make sure that now underCLSID = {yourAppIdHere} [DllSurrogate] =is listed among the entries.
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 theClsidkey.
- 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 beAppIDand data should be the same COM object GUID you have just searched for.
- 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 itDllSurrogate. Leave the value empty.
- 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.
That’s it, your COM Object should now be accessible from a 64bit environment and can be used like a regular COM Object.
- 30,962
- 25
- 85
- 135
- 149
- 1
- 8






