Solved

CreateObject - ProgId

Posted on 1999-01-13
13
2,305 Views
Last Modified: 2009-01-09
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.
0
Comment
Question by:bav061998
  • 5
  • 5
  • 2
  • +1
13 Comments
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1455999
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
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 1456000
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.
0
 

Author Comment

by:bav061998
ID: 1456001
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.

0
 

Expert Comment

by:nangstadt
ID: 1456002
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.
0
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1456003
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?

0
 

Expert Comment

by:nangstadt
ID: 1456004
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.
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:bav061998
ID: 1456005
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.
0
 

Author Comment

by:bav061998
ID: 1456006
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.

0
 

Expert Comment

by:nangstadt
ID: 1456007
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.
0
 

Author Comment

by:bav061998
ID: 1456008
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...

0
 

Expert Comment

by:nangstadt
ID: 1456009
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.
0
 

Author Comment

by:bav061998
ID: 1456010
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.


0
 

Accepted Solution

by:
nangstadt earned 60 total points
ID: 1456011
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.

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.

Thanks,
Nathan
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Copy exact format 27 100
Need to convert a simple VB script to PowerShell 3 54
Copy a row 12 53
Running Visio Macro from VBS File 3 36
Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now