Link to home
Start Free TrialLog in
Avatar of bav061998
bav061998

asked on

CreateObject - ProgId

I am using an ActiveX DLL developed by someone else (I guess, it's developed using Visual C++).

From VB5.0, I make a reference to it in the project and create objects using New Keyword. Everything works perfect.
However for some reason, I do not want to refer to it in the project but later on create the objects using CreateObject (don't bother suggesting it's better to refer to it in the project. I have to use the CreateObject, whatever the reason may be).

Now to use CreateObject I wanted the ProgId and tried to get it from running regedt32.exe. I see the following entries:

Under HKEY_CLASSES_ROOT,

X.X, value data as X Class
-> CurVer, value data as X.X.1

X.X.1, value data as X Class
-> CLSID, value data A4A6..... so on specifying the class id.

Under HKEY_CLASSES_ROOT\CLSID\A4A6.... so on,

InProcServer32, value data as c:\winnt\system32\XXXXXX~1.DLL
ProgId, value data as X.X.1
Programmable, <value not set>
VersionIndependentProgID, value data X.X

I was in the impression that I can use VersionIndependentProgID. However in this case, if I use "X.X" as ProgId with CreateObject I am unable to create the object. It's as if it cannot find that ProgId. However, if I use "X.X.1" as ProId with CreateObject I am able to create the object and everything seems to work fine.

Isn't that .1 version information? Can anybody tell me why is this so? Should I be registering in any different way? Currently I am registering using the command,
regsvr32 /v "c:\winnt\system32\xxxxxxxxxx.dll"
(Tried withour /v as well)
Or is it anything to do with while compiling in VC++?

Could anyone detail me on this? Thank you and look forward to your answer.
Avatar of Mirkwood
Mirkwood

1)
The problem is that there are some obsolete registry entries still in this registry
Run regclean, you can download it from the microsoft site.
That will most likely solve your problem.
2)
The registration of the dll is not right. The installation code is wrong and set the wrong registry entries.

Note: The should be a current version entry in case that you use the prog id version numbering system. Take a look at Word.Document in the registry
I was looking at my own registry using Word.Basic and it seems to me that Mirkwood is right.
Using RegClean I've often found that it cleans out a lot of unnecessary rubbish from the registry (which is great) except the stuff that I REALLY wanted it to remove (alas) and many a time I've had to go in and manually clean up.

Have fun... be careful.
Avatar of bav061998

ASKER

No, I do not want to use RegClean. I had used it long back and it did a lot to me, I had to re-install some of the softwares again!

Anyway, I have tried manually cleaning up X.X and X.X.1 related entries and registering it again. Checked this again after reading your notes now, I see the same result.

Mirkwood, what do you mean by "The installation code is wrong..." ? I do not have a setup program for this. I register it manually.

The problem is that the CreateObject function needs to have a CLSID associated with each ProgID.  The CurVer is not enough.  Microsoft provides a number of ways to accomplish this, the easiest is to add a CLSID entry to the Version Independent Class.  Check entries for Microsoft Office products i.e. Excel.Application.  Software created using Visual Studio tools does not automatically generate this entry so you must do it manually.  While you are looking at how the Microsoft Office components are registered, go to the CLSID and look for AutoConvertTo to see another way of handling this problem.
When it's registered manually, you are actually calling some registration code within the DLL. There might be a bug in this code. Is it a VB dll or something else?

It appears from the registration signature that this component was created using ATL.  ATL projects manage registration through the use of a .rgs file.  By default, the ATL project will not contain the entries required to ues the version independent ProgID.  If you have access to the project, simple make the required changes, otherwise contact your vendor.
Mirkwood, when I said I registered manually, I meant I used
regsvr32 /v "c:\winnt\system32\xxxxxxxxxx.dll"  
as I said in my posting. This is the generic utility from MicroSoft that can be used to register ActiveX DLLs. I don't know, I cannot yet say this is causing the problem.
nangstadt, I don't like the idea of adding CLASS ID manually. I don't think that's a solution. I did not understand anything by looking at AutoConvertTo.

Anyway, your comment later makes little sense. However, I do not have access to that project and have little knowledge about ATL Projects. I will try to contact the vendor and in the meantime I will keep this open for any further hints/discussion.

The bottom line is that if you want to use CreateObject, you either need to use the fully qualified ProgID i.e. 'component.coclass.version' or you need to have the CLSID in your version independent ProgID registry entry.  This is due to the fact that New and CreateObject use vastly different methods to actually instantiate your object.  The New keyword uses the COM CoCreateInstance API while CreateObject function uses the COM CoGetClassObject and MkParseDisplayName API's and a ClassMoniker.  If you do not have access to the project, you should contact the vendor to get the registry update corrected.  Until then you will need to have a work around to get the CLSID into the registry.  The simplest way is to create a registry import file (.reg).  By the way, all dll components should ultimately be registered by calling into an exported funtion called DllRegisterServer.  RegSvr32 is nothing more than a simple application that loads the dll and makes a call to DllRegisterServer.  A component that provides the DllRegisterServer function is known as a self-registering component.  As all dll components should support self-registration, most developers refer to manual registering as going into a program such as regedit and "manually" making changes.
nangstadt, thank you for that detailed note. Still that does not tell me why the dll registry process (RegSvr32 or DLLRegisterServer or whatever) did not add CLSID for VersionIndependentProgID registry entry.

This is not the first time I am using ActiveX DLL, I have seen it many times (again whatever process you follow) registering the DLL correctly so that it can be used by CreateObject or New without any more tinkering.

As you said, it may be something to do with Project Properties.
Yet to figure out...

Lets start from the beginning.  When the component is distributed, it must be registered before it can be used as a COM component.  If a dll component supports self-registration, it must export a function called DllRegisterServer.  To accomplish this, someone, somewhere (i.e. RegSvr32.exe) will dynamically load the dll through a call to LoadLibrary, get the address of the DllRegisterServer function through a call to GetProcAddress, and call the function.  It is up to the implementor of the DllRegisterServer function to actually make the registry updates, as they require for their component.  What gets put in the registry has nothing whatsoever to do with VB, RegSvr32.exe, or anyone else but the DllRegisterServer function.  As I wrote previously it appears that this component was written using ATL.  I say this because a default ATL project will put precisely the entries, that you described, in the registry.  This however is not enough to support the use of CreateObject, or for that matter GetObject.  To fix the problem, the implementor of the project will need to make a fix to what happens when his DllRegisterServer function is called.
nangstadt, the confusion here is you are coming from Visual C++ background (I guess) and thus you talk in those terms where as I am coming from Visual Basic background so I talk in those terms ;-)

In VB when you create an ActiveX Component, exporting DllRegisterServer function or supporting self-registration ... all that happens by magic! and things do happen correctly (I believe). As per my knowledge programmer has no control in those area what so ever.

That's why, I was not convinced. I played around a bit in VC++ and ATL Project this weekend, now what you said is making sense. I haven't heard from my vendor yet, but anyway I would like to go ahead and grant you the points.

So, please submit an answer for your points. Thank you.


ASKER CERTIFIED SOLUTION
Avatar of nangstadt
nangstadt

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial