Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CreateComObject - Class not registered

1,413 views
Skip to first unread message

Rolf Lampa [RIL]

unread,
Jun 6, 2008, 8:12:03 PM6/6/08
to
Hi all,

I created a COM object using the COM Object wizard (D7), then compiled and
registered the COM object, like so:

"<path>\TRegSvr.exe MyComObject.exe

...which reported:

"MyComObject.exe /regserver successfully called"

Using the _TLB.pas file from another application compiles fine but when try to
create a CoClass of my COM object with this code:

MwIndex := CoMyComObject.Create; // as IMyComObject;

... I only get an error message saying "class not registered". I use XPSP3, D7.

Any ideas why this doesn't work?

Regards,

// Rolf Lampa

Marc Rohloff [TeamB]

unread,
Jun 6, 2008, 10:57:33 PM6/6/08
to
On Sat, 07 Jun 2008 02:12:03 +0200, Rolf Lampa [RIL] wrote:

> ... I only get an error message saying "class not registered". I use XPSP3, D7.
>
> Any ideas why this doesn't work?

Start by looking in the registry under
HKEY_CLASSES_ROOT\CLSID\{000...}
where {000...} is your co classes id.

You could also try the project\import type library option in Delphi 7.
This will give you a list of registered type libraries.

I suspect that this is not being created. My first suspicion would be
that your type library is not being included in the EXE, the second
would be that something is preventing the EXE from registering. Option
#3 is that somehow the EXE and the TLB file you are using use a
different CoClass ID.

--
Marc Rohloff [TeamB]
marc -at- marc rohloff -dot- com

Rolf Lampa [RIL]

unread,
Jun 7, 2008, 11:17:11 AM6/7/08
to
Rolf Lampa [RIL] skrev:

> Marc Rohloff [TeamB] wrote:
>> Rolf Lampa [RIL] wrote:
>>
>>> ... I only get an error message saying "class not registered". I use
>>> XPSP3, D7.
>>>
>>> Any ideas why this doesn't work?
>>
>> Start by looking in the registry under
>> HKEY_CLASSES_ROOT\CLSID\{000...}
>> where {000...} is your co classes id.
>
> I can find only a LibID, and the interface ID under
> HKEY_CLASSES_ROOT\Interface
>
> ... but no class ID found under CLSID.

Must the CLSID be registered somehow separately?

// Rolf Lampa

Rolf Lampa [RIL]

unread,
Jun 7, 2008, 11:12:54 AM6/7/08
to
Marc Rohloff [TeamB] skrev:

> On Sat, 07 Jun 2008 02:12:03 +0200, Rolf Lampa [RIL] wrote:
>
>> ... I only get an error message saying "class not registered". I use XPSP3, D7.
>>
>> Any ideas why this doesn't work?
>
> Start by looking in the registry under
> HKEY_CLASSES_ROOT\CLSID\{000...}
> where {000...} is your co classes id.

I can find only a LibID, and the interface ID under
HKEY_CLASSES_ROOT\Interface

... but no class ID found under CLSID.

>

> You could also try the project\import type library option in Delphi 7.
> This will give you a list of registered type libraries.

I can see it in the list...


> I suspect that this is not being created. My first suspicion would be
> that your type library is not being included in the EXE,

In "TheOtherApp.EXE" (.dpr file) I have the line

MyComObject_TLB in '..\MyComObject_TLB.pas',

> the second
> would be that something is preventing the EXE from registering. Option
> #3 is that somehow the EXE and the TLB file you are using use a
> different CoClass ID.

CoClass ID is not the same as the Interface ID. In the method
"CoMyComObject.Create" the CLASS (Guid) is casted to IID (Guid):
Result := CreateComObject(CLASS_MyComObject) as IMyComObject;

(See the _TLB.pas file below).

Or, can it be something with the flags which makes registration fail?

flags for IMyComObject:
[ ] Hidden
[ ] Dual
[x] Ole Automation
[ ] Nonextensible

flags for MyComObject:
[ ] Hidden
[x] Can Create
[ ] Application Object
[ ] Licensed
[ ] Control
[ ] Replaceable
[ ] Aggregatable


unit MyComObject_TLB;

// ************************************************************************ //
// WARNING
// -------
// The types declared in this file were generated from data read from a
// Type Library. If this type library is explicitly or indirectly (via
// another type library referring to this type library) re-imported, or the
// 'Refresh' command of the Type Library Editor activated while editing the
// Type Library, the contents of this file will be regenerated and all
// manual modifications will be lost.
// ************************************************************************ //

// PASTLWTR : 1.2
// File generated on 2008-06-07 14:22:03 from Type Library described below.

// ************************************************************************ //
// Type Lib: E:\Projects_D\MyObjectCOM\MyComObject.tlb (1)
// LIBID: {3367DA7E-5D6B-44F3-99F6-D51B7DFAB29F}
// LCID: 0
// Helpfile:
// HelpString: MyComObject Library
// DepndLst:
// (1) v2.0 stdole, (C:\WINDOWS\system32\stdole2.tlb)
// ************************************************************************ //
{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers.
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface

uses Windows, ActiveX, Classes, Graphics, StdVCL, Variants;


// *********************************************************************//
// GUIDS declared in the TypeLibrary. Following prefixes are used:
// Type Libraries : LIBID_xxxx
// CoClasses : CLASS_xxxx
// DISPInterfaces : DIID_xxxx
// Non-DISP interfaces: IID_xxxx
// *********************************************************************//
const
// TypeLibrary Major and minor versions
MyComObjectMajorVersion = 1;
MyComObjectMinorVersion = 1;

LIBID_MyComObject: TGUID = '{3367DA7E-5D6B-44F3-99F6-D51B7DFAB29F}';

IID_IMyComObject: TGUID = '{130D0868-4E9C-4749-88F5-5FB3BF093590}';
CLASS_MyComObject: TGUID = '{14EBDA4F-435F-4F07-8AEC-D1442DE722D8}';
type

// *********************************************************************//
// Forward declaration of types defined in TypeLibrary
// *********************************************************************//
IMyComObject = interface;

// *********************************************************************//
// Declaration of CoClasses defined in Type Library
// (NOTE: Here we map each CoClass to its Default Interface)
// *********************************************************************//
MyComObject = IMyComObject;


// *********************************************************************//
// Interface: IMyComObject
// Flags: (256) OleAutomation
// GUID: {130D0868-4E9C-4749-88F5-5FB3BF093590}
// *********************************************************************//
IMyComObject = interface(IUnknown)
['{130D0868-4E9C-4749-88F5-5FB3BF093590}']
function GetSomeValue(const aString: WideString): Int64; stdcall;
end;

// *********************************************************************//
// The Class CoMyComObject provides a Create and CreateRemote method to
// create instances of the default interface IMyComObject exposed by
// the CoClass MyComObject. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// *********************************************************************//
CoMyComObject = class
class function Create: IMyComObject;
class function CreateRemote(const MachineName: string): IMyComObject;
end;

implementation

uses ComObj;

class function CoMyComObject.Create: IMyComObject;
begin
Result := CreateComObject(CLASS_MyComObject) as IMyComObject;
end;

class function CoMyComObject.CreateRemote(const MachineName: string): IMyComObject;
begin
Result := CreateRemoteComObject(MachineName, CLASS_MyComObject) as IMyComObject;
end;

end.


Regards,

// Rolf Lampa

Marc Rohloff [TeamB]

unread,
Jun 7, 2008, 3:12:05 PM6/7/08
to
On Sat, 07 Jun 2008 17:17:11 +0200, Rolf Lampa [RIL] wrote:

> I can find only a LibID, and the interface ID under
> HKEY_CLASSES_ROOT\Interface
> ... but no class ID found under CLSID.

Then I suspect that your class is registered under a different ID.

> > You could also try the project\import type library option in Delphi 7.
> > This will give you a list of registered type libraries.

> I can see it in the list...

So if you import it how does the file compare to what you already
have?


> In "TheOtherApp.EXE" (.dpr file) I have the line
> MyComObject_TLB in '..\MyComObject_TLB.pas',

This is not enough. here is usually a line (in the DPR I think)
something like:
{$R "MYComObject.tlb"}


> CoClass ID is not the same as the Interface ID. In the method
> "CoMyComObject.Create" the CLASS (Guid) is casted to IID (Guid):
> Result := CreateComObject(CLASS_MyComObject) as IMyComObject;

No its not. A ClassID (or sometimes a ProgID which maps to a ClassID)
is used to decide which object to create. It is possible to have more
than one object implementing the same interface.

> Must the CLSID be registered somehow separately?

Yes, there must be a HKCU\CLSID entry, this tells the system the name
of the executable or dll containing the implementation.

Rolf Lampa [RIL]

unread,
Jun 7, 2008, 9:09:46 PM6/7/08
to
Marc Rohloff [TeamB] skrev:

> On Sat, 07 Jun 2008 17:17:11 +0200, Rolf Lampa [RIL] wrote:
>
>> I can find only a LibID, and the interface ID under
>> HKEY_CLASSES_ROOT\Interface
>> ... but no class ID found under CLSID.
>
> Then I suspect that your class is registered under a different ID.

Thank you very much for your help, I tried it all, but D7 seem to have decided
it won't let me succeed. I resorted to try to create the COM object in D2006 -
and then it works fine! <Sigh>

Only one problem, when I try to return a string as a function result it crashes
silently:

IMyComObject = interface(IUnknown)
['{40FF5769-6DC3-4015-84CE-9AC366973F0B}']
...
function TitleByIndex(aIndex: SYSINT): WideString; stdcall;

Implementation:

function TMyComObject.TitleByIndex(aIndex: SYSINT): WideString;
// TitleList = TStringList
begin
Result := '';
if (aIndex > -1) and (aIndex < TitleList.Count) then
Result := TitleList[aIndex];
end;

The .tlb for "TitleByIndex" looks like this:

BSTR _stdcall TitleByIndex([in] int aIndex );

Other functions returning Integers or Boolean (Int & VARIANT_BOOL) works as
expected, but not string. What am I doing wrong?

Regards,

// Rolf Lampa

Rolf Lampa [RIL]

unread,
Jun 8, 2008, 2:04:50 AM6/8/08
to
Marc Rohloff [TeamB] skrev:

> On Sat, 07 Jun 2008 17:17:11 +0200, Rolf Lampa [RIL] wrote:
>
>> I can find only a LibID, and the interface ID under
>> HKEY_CLASSES_ROOT\Interface
>> ... but no class ID found under CLSID.
>
> Then I suspect that your class is registered under a different ID.


Can't find the class at all under CLSID (searching both by name and ID).

>>> You could also try the project\import type library option in Delphi 7.
>>> This will give you a list of registered type libraries.
>
>> I can see it in the list...
>
> So if you import it how does the file compare to what you already
> have?

Same thing, except for some added lines enabling design time access to the
object. Same problem when trying to start it:
"Class not registered, ClassID: {...}"


>> In "TheOtherApp.EXE" (.dpr file) I have the line
>> MyComObject_TLB in '..\MyComObject_TLB.pas',
>
> This is not enough. here is usually a line (in the DPR I think)
> something like:
> {$R "MYComObject.tlb"}

Yup, it's there.


>> CoClass ID is not the same as the Interface ID. In the method
>> "CoMyComObject.Create" the CLASS (Guid) is casted to IID (Guid):
>> Result := CreateComObject(CLASS_MyComObject) as IMyComObject;
>
> No its not. A ClassID (or sometimes a ProgID which maps to a ClassID)
> is used to decide which object to create. It is possible to have more
> than one object implementing the same interface.
>
>> Must the CLSID be registered somehow separately?
>
> Yes, there must be a HKCU\CLSID entry, this tells the system the name
> of the executable or dll containing the implementation.


Well, how do I get it in there?

Once I tried creating it all from scratch in D2006, and then it worked! But then
after som editing the .tlb file crashed, and after that I tried recreating it
again but now it's the same thing again.

After this I have tried to unregister and register again, and searched the
registry for both ID's and clear text and then manually removed all traces, and
then tried to re-register again, but no.

It should work automagically, after having started the COM object-app once
(which it also did at first when using D2006). Strange.

Regards,

// Rolf Lampa

Rolf Lampa [RIL]

unread,
Jun 9, 2008, 8:45:22 AM6/9/08
to


Does anyone know how to manually register the CLSID? I've tried to register
manually but obviously I didn't add enough keys, or with incorrect data. I can
get it stop complaining about "class not registered, ClassID: {..." but instead
it complains (after attempting to connect for a while) that the server activity
wasn't successful (forgot the exact message).

Does anyone have an idea, or a link? (I have tried google but didn't find any
relevant description/solution).

Short version: How do I register the ClassID in registry (not only ProgID and
LibID)?

Regards,

// Rolf Lampa

Marc Rohloff [TeamB]

unread,
Jun 9, 2008, 8:53:12 AM6/9/08
to
On Sun, 08 Jun 2008 08:04:50 +0200, Rolf Lampa [RIL] wrote:

> Well, how do I get it in there?

I am sure it is something simple, but the only way I know of figuring
it out is to enable debug dcu's, start your app with the /regserver
parameter and start debugging.

Rolf Lampa [RIL]

unread,
Jun 9, 2008, 9:55:53 AM6/9/08
to
Marc Rohloff [TeamB] skrev:

> On Sun, 08 Jun 2008 08:04:50 +0200, Rolf Lampa [RIL] wrote:
>
>> Well, how do I get it in there?
>
> I am sure it is something simple, but the only way I know of figuring
> it out is to enable debug dcu's, start your app with the /regserver
> parameter and start debugging.

I'm not sure of exactly how you meant (the app containing the COM object, or the
client?). I do have debug Dcu's enabled, and I started the COM app with
/regserver, but that doesn't give me more info than I had before.

What I know, and what I knew before is that where it fails when I try to start
the COM object application:

(in the unit ComObj OleCheck against hex EEEEEE):

function CreateComObject(const ClassID: TGUID): IUnknown;
begin
OleCheck(CoCreateInstance(ClassID, nil, CLSCTX_INPROC_SERVER or
CLSCTX_LOCAL_SERVER, IUnknown, Result));
end;

{ Raise EOleSysError exception if result code indicates an error }

procedure OleCheck(Result: HResult);
begin
if not Succeeded(Result) then OleError(Result);
end;

// and here I get this "class not registered" error msg.

Or did you mean something else?

Regards,

// Rolf Lampa

Marc Rohloff [TeamB]

unread,
Jun 9, 2008, 11:12:49 AM6/9/08
to
On Mon, 09 Jun 2008 14:45:22 +0200, Rolf Lampa [RIL] wrote:

> Short version: How do I register the ClassID in registry (not only ProgID and
> LibID)?

Technically you don't need a LibID or ProgID registered. FOr he Class
ID I believe that you need to create
HKCU\CLSID\{XXXX-XXX}
HKCU\CLSID\{XXXX-XXX}\LocalServer
HKCU\CLSID\{XXXX-XXX}\LocalServer32

Marc Rohloff [TeamB]

unread,
Jun 9, 2008, 11:17:25 AM6/9/08
to
On Mon, 09 Jun 2008 15:55:53 +0200, Rolf Lampa [RIL] wrote:

>> I am sure it is something simple, but the only way I know of figuring
>> it out is to enable debug dcu's, start your app with the /regserver
>> parameter and start debugging.
>
> I'm not sure of exactly how you meant (the app containing the COM object, or the
> client?). I do have debug Dcu's enabled, and I started the COM app with
> /regserver, but that doesn't give me more info than I had before.

I meant the server not the client. Set the command line parameters to
/regserver, open the 'ComServ.pas' file and put a break point at the
beginning of the initialization section and start figuring out what
happens from there.

Remy Lebeau (TeamB)

unread,
Jun 9, 2008, 1:29:05 PM6/9/08
to

"Rolf Lampa [RIL]" <rolf....@rilnet.will.do.fine.com> wrote in message
news:4849d253$1...@newsgroups.borland.com...

> Any ideas why this doesn't work?

Your COM object is not registered correctly. Is your client app running in
same user account that registered the COM object?


Gambit


Rolf Lampa [RIL]

unread,
Jun 9, 2008, 2:00:30 PM6/9/08
to
Marc Rohloff [TeamB] skrev:

> On Mon, 09 Jun 2008 14:45:22 +0200, Rolf Lampa [RIL] wrote:
>
>> Short version: How do I register the ClassID in registry (not only ProgID and
>> LibID)?
>
> Technically you don't need a LibID or ProgID registered. FOr he Class
> ID I believe that you need to create
> HKCU\CLSID\{XXXX-XXX}
> HKCU\CLSID\{XXXX-XXX}\LocalServer
> HKCU\CLSID\{XXXX-XXX}\LocalServer32
>


Hi again, and thank you for trying to help, I appreciate that a lot.

I assume HKCU means HKEY_CURRENT_USER, but, there is no sub directory "\CLSID"
under HKEY_CURRENT_USER. Under HKEY_CLASSES_ROOT there is, though. Could it
possibly be that you meant HKEY_CLASSES_ROOT? (well, I'll try that first and see).

Regards,

// Rolf Lampa

Rolf Lampa [RIL]

unread,
Jun 9, 2008, 2:26:51 PM6/9/08
to
Remy Lebeau (TeamB) skrev:

(trying to register the ClassID manually according to Marc Rohloff's
instructions, no success so far though, but I continue to add more info in the
keys and keep trying...)

Yes. I only "extracted" one single object (holding a TStringList title index)
into its own application which implements a COM object.

The application name is MediawikiComIndex.exe, and thus the _TLB.pas and .tlb
are automagically named (using the COM object wizzard):

- MediawikiComIndex_TLB.pas and
- MediawikiComIndex.tlb respectively.

The class name entered in the .tlb-editor is MediawikiIndex, with IInterface
name IMediawikiIndex (and the implementation class TMediawikiIndex). That's it.
Only 5 methods, and that's it.

The COM app starts like this:

program MediawikiComIndex;

uses
Forms,
FMain in 'FMain.pas' {MainForm},
UMediawikiIndex in 'UMediawikiIndex.pas' {MediawikiIndex: CoClass},
MediawikiComIndex_TLB in 'MediawikiComIndex_TLB.pas';

{$R *.TLB}

{$R *.res}

begin
Application.Initialize;
Application.CreateForm(TfrmMain, MainForm);
Application.Run;
end.

Remy Lebeau (TeamB)

unread,
Jun 9, 2008, 2:42:18 PM6/9/08
to

"Rolf Lampa [RIL]" <rolf....@rilnet.will.do.fine.com> wrote in message
news:484d6fbd$1...@newsgroups.borland.com...

> I assume HKCU means HKEY_CURRENT_USER

Yes.

> there is no sub directory "\CLSID" under HKEY_CURRENT_USER.

Under HKCU and HKLM, you have to use '\Software\Classes\CLSID' instead.
'\CLSID' applies to the HKEY_CLASSES_ROOT key instead. HKEY_CLASSES_ROOT is
a merged view of the 'HKLM\Software\Classes' and 'HKCU\Software\Classes'
keys.


Gambit


Remy Lebeau (TeamB)

unread,
Jun 9, 2008, 2:56:24 PM6/9/08
to

"Rolf Lampa [RIL]" <rolf....@rilnet.will.do.fine.com> wrote in message
news:484d...@newsgroups.borland.com...

> (trying to register the ClassID manually according to Marc
> Rohloff's instructions, no success so far though, but I
> continue to add more info in the keys and keep trying...)

Based on the information you have provided so far, your Registry keys should
contain something like the following:

HKEY_CLASSES_ROOT\TypeLib\{3367DA7E-5D6B-44F3-99F6-D51B7DFAB29F}\1.0\0\win32
@="E:\Projects_D\MyObjectCOM\MyComObject.tlb"

HKEY_CLASSES_ROOT\Interface\{130D0868-4E9C-4749-88F5-5FB3BF093590}
@="IMyComObject"

HKEY_CLASSES_ROOT\Interface\{130D0868-4E9C-4749-88F5-5FB3BF093590}\TypeLib
@="{3367DA7E-5D6B-44F3-99F6-D51B7DFAB29F}"

HKEY_CLASSES_ROOT\CLSID\{14EBDA4F-435F-4F07-8AEC-D1442DE722D8}
@="MyComObject Library"

HKEY_CLASSES_ROOT\CLSID\{14EBDA4F-435F-4F07-8AEC-D1442DE722D8}\LocalServer32
@="E:\Projects_D\MyObjectCOM\MediawikiComIndex.exe"

HKEY_CLASSES_ROOT\CLSID\{14EBDA4F-435F-4F07-8AEC-D1442DE722D8}\TypeLib
@="{3367DA7E-5D6B-44F3-99F6-D51B7DFAB29F}"


Gambit


Rolf Lampa [RIL]

unread,
Jun 9, 2008, 2:53:07 PM6/9/08
to
Remy Lebeau (TeamB) skrev:

> "Rolf Lampa [RIL]" <rolf....@rilnet.will.do.fine.com> wrote in message
> news:484d6fbd$1...@newsgroups.borland.com...
>
>> I assume HKCU means HKEY_CURRENT_USER
>
> Yes.
>
>> there is no sub directory "\CLSID" under HKEY_CURRENT_USER.
>
> Under HKCU and HKLM, you have to use '\Software\Classes\CLSID' instead.

Will I need to register the class in both?

> '\CLSID' applies to the HKEY_CLASSES_ROOT key instead. HKEY_CLASSES_ROOT is
> a merged view of the 'HKLM\Software\Classes' and 'HKCU\Software\Classes'
> keys.


Will that merging take place automagically?

Regards,

// Rolf Lampa

Marc Rohloff [TeamB]

unread,
Jun 9, 2008, 4:00:08 PM6/9/08
to
On Mon, 09 Jun 2008 20:00:30 +0200, Rolf Lampa [RIL] wrote:

> I assume HKCU means HKEY_CURRENT_USER, but, there is no sub directory "\CLSID"
> under HKEY_CURRENT_USER. Under HKEY_CLASSES_ROOT there is, though. Could it
> possibly be that you meant HKEY_CLASSES_ROOT? (well, I'll try that first and see).

Yes, I meant HKCL.

From what you describe further down there is obviously something
really wrong. Why don't you try with a new simple server using the
demos or wizards and get that working?

Rolf Lampa [RIL]

unread,
Jun 9, 2008, 3:48:00 PM6/9/08
to
Remy Lebeau (TeamB) skrev:

> "Rolf Lampa [RIL]" <rolf....@rilnet.will.do.fine.com> wrote in message
> news:484d...@newsgroups.borland.com...
>
>> (trying to register the ClassID manually according to Marc
>> Rohloff's instructions, no success so far though, but I
>> continue to add more info in the keys and keep trying...)
>
> Based on the information you have provided so far, your Registry keys should
> contain something like the following:
>
> HKEY_CLASSES_ROOT\TypeLib\{3367DA7E-5D6B-44F3-99F6-D51B7DFAB29F}\1.0\0\win32
> @="E:\Projects_D\MyObjectCOM\MyComObject.tlb"

Passed.


> HKEY_CLASSES_ROOT\Interface\{130D0868-4E9C-4749-88F5-5FB3BF093590}
> @="IMyComObject"

Passed.

Also the ..\TypeLib is correct (same Guid as above).


> HKEY_CLASSES_ROOT\Interface\{130D0868-4E9C-4749-88F5-5FB3BF093590}\TypeLib
> @="{3367DA7E-5D6B-44F3-99F6-D51B7DFAB29F}"

Passed.


> HKEY_CLASSES_ROOT\CLSID\{14EBDA4F-435F-4F07-8AEC-D1442DE722D8}
> @="MyComObject Library"

Passed.


> HKEY_CLASSES_ROOT\CLSID\{14EBDA4F-435F-4F07-8AEC-D1442DE722D8}\LocalServer32
> @="E:\Projects_D\MyObjectCOM\MediawikiComIndex.exe",

Passed.


> HKEY_CLASSES_ROOT\CLSID\{14EBDA4F-435F-4F07-8AEC-D1442DE722D8}\TypeLib
> @="{3367DA7E-5D6B-44F3-99F6-D51B7DFAB29F}"

Passed.

Now trying to call the COM object from the other application:

- Failed. (after attempting to connect for a loooong time, it starts the COM
app, but a call to the object method "LoadIndexFromFile" returns the msg "server
execution failed" (in Swedish "serverkörning misslyckades").

Regards,

// Rolf Lampa

Rolf Lampa [RIL]

unread,
Jun 9, 2008, 4:20:50 PM6/9/08
to
Marc Rohloff [TeamB] skrev:

> On Mon, 09 Jun 2008 20:00:30 +0200, Rolf Lampa [RIL] wrote:
>
>> I assume HKCU means HKEY_CURRENT_USER, but, there is no sub directory "\CLSID"
>> under HKEY_CURRENT_USER. Under HKEY_CLASSES_ROOT there is, though. Could it
>> possibly be that you meant HKEY_CLASSES_ROOT? (well, I'll try that first and see).
>
> Yes, I meant HKCL.
>
> From what you describe further down there is obviously something
> really wrong. Why don't you try with a new simple server using the
> demos or wizards and get that working?


I have tried that, three times. Only once it worked (using the COM
object wizard from d2006), well, until something happened with the
.tlb (lost sync with _TLB.pas) and then I got the same problem
again.

I could try several times like that yes, perhaps I'd get it to work
then, but I need to for sure how to restore contact with the object
if I lose it again...

So no, I won't rely on chance only. :)

Regards,

// Rolf Lampa

Remy Lebeau (TeamB)

unread,
Jun 9, 2008, 4:16:18 PM6/9/08
to

"Rolf Lampa [RIL]" <rolf....@rilnet.will.do.fine.com> wrote in message
news:484d...@newsgroups.borland.com...

> Now trying to call the COM object from the other application:


>
> - Failed. (after attempting to connect for a loooong time, it starts
> the COM app

Sounds like your COM server is taking too long to initialize itself when
run. Have you tried the same test with the .exe already running beforehand?

> a call to the object method "LoadIndexFromFile" returns the
> msg "server execution failed" (in Swedish "serverkörning
> misslyckades").

What is the actual HRESULT that is being returned?


Gambit


Remy Lebeau (TeamB)

unread,
Jun 9, 2008, 4:14:24 PM6/9/08
to

"Rolf Lampa [RIL]" <rolf....@rilnet.will.do.fine.com> wrote in message
news:484d7c11$1...@newsgroups.borland.com...

> Will I need to register the class in both?

Register under HKLM if you want it accessible to all users. Register under
HKCU if you want it accessible to only specific user(s).

> Will that merging take place automagically?

I suggest you read MSDN's documentation on how HKCR actually works:

HKEY_CLASSES_ROOT Key
http://msdn.microsoft.com/en-us/library/ms724475.aspx

Merged View of HKEY_CLASSES_ROOT
http://msdn.microsoft.com/en-us/library/ms724498(VS.85).aspx


Gambit


Rolf Lampa [RIL]

unread,
Jun 9, 2008, 4:35:05 PM6/9/08
to
Remy Lebeau (TeamB) wrote:
> "Rolf Lampa [RIL]" wrote

> Register under HKLM if you want it accessible to all users. Register under

> HKCU if you want it accessible to only specific user(s).
>
>> Will that merging take place automagically?
>
> I suggest you read MSDN's documentation on how HKCR actually works:
>
> HKEY_CLASSES_ROOT Key
> http://msdn.microsoft.com/en-us/library/ms724475.aspx
>
> Merged View of HKEY_CLASSES_ROOT
> http://msdn.microsoft.com/en-us/library/ms724498(VS.85).aspx

OK, now I have read it. Seems like the merging takes place automagically.

Regards,

// Rolf Lampa

Rolf Lampa [RIL]

unread,
Jun 10, 2008, 12:41:54 AM6/10/08
to
Remy Lebeau (TeamB) skrev:

> "Rolf Lampa [RIL]" <rolf....@rilnet.will.do.fine.com> wrote in message
> news:484d...@newsgroups.borland.com...
>
>> Now trying to call the COM object from the other application:
>>
>> - Failed. (after attempting to connect for a loooong time, it starts
>> the COM app
>
> Sounds like your COM server is taking too long to initialize itself when
> run. Have you tried the same test with the .exe already running beforehand?

Yes I have tried that, but it starts new instances, so the problem is the same.

I would, btw, like to have only one instance ("Singleton"). How should I set
ThreadingModel and the ClassInstancing parameters in order to create only one
COM instance ("Singleton") shared by several applications (a combination of these):

(from ComServ)

Instancing mode for COM classes:
(*ciInternal, ciSingleInstance, ciMultiInstance*);
Threading model supported by COM classes:
(*tmSingle, tmApartment, tmFree, tmBoth, tmNeutral*);

At first I thought that "ciInternal, tmBoth" would do.


>> a call to the object method "LoadIndexFromFile" returns the
>> msg "server execution failed" (in Swedish "serverkörning
>> misslyckades").
>
> What is the actual HRESULT that is being returned?

Wrong of me. My app never reaches as far as to call any method at all, I don't
even get a valid object :

fComTitleIndex := CoMediawikiIndex.Create; //IMediawikiIndex; <- fails
if not ComTitleIndex.IsInitialized then
// ... never reaching this far

This is insane, I start getting this creepy feeling about COM...

I tried to document all registry settings I could recognize, and from that make
my own .reg file achieving the same result. See far below the current one. What
seems missing or incorrect in it?

Regards,

// Rolf Lampa


My .reg -file for the COM server, based the following files, paths and types:

E:\Projects_MW\MediawikiComIndex\MediawikiComIndex.dpr
E:\Projects_MW\MediawikiComIndex\MediawikiComIndex.exe
E:\Projects_MW\MediawikiComIndex\MediawikiComIndex.tlb
E:\Projects_MW\MediawikiComIndex\MediawikiComIndex_TLB.pas
CoClass MediawikiIndex
Interface IMediawikiIndex
Class name TMediawikiIndex
-

<.reg file>
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MediawikiComIndex]
@="MediawikiIndex Class"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MediawikiComIndex\CLSID]
@="{0C55F68B-7FEF-41CD-A184-C094F70A7124}"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0C55F68B-7FEF-41CD-A184-C094F70A7124}]
@="MediawikiIndex"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0C55F68B-7FEF-41CD-A184-C094F70A7124}\LocalServer]
@="E:\\Projects_MW\\MediawikiComIndex\\MediawikiComIndex.exe"
"ThreadingModel"="Both"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0C55F68B-7FEF-41CD-A184-C094F70A7124}\LocalServer32]
@="E:\\Projects_MW\\MediawikiComIndex\\MediawikiComIndex.exe"
"ThreadingModel"="Both"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0C55F68B-7FEF-41CD-A184-C094F70A7124}\TypeLib]
@="{814CC12B-836F-4898-8990-23D998C565E8}"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0C55F68B-7FEF-41CD-A184-C094F70A7124}\ProgID]
@="MediawikiComIndex"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0C55F68B-7FEF-41CD-A184-C094F70A7124}\Version]
@="1.2"

; -----------------------------------------------------------------------------

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{814CC12B-836F-4898-8990-23D998C565E8}\1.2]
@="MediawikiComIndex Library"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{814CC12B-836F-4898-8990-23D998C565E8}\1.2\0\win32]
@="E:\\Projects_MW\\MediawikiComIndex\\MediawikiComIndex.exe"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{814CC12B-836F-4898-8990-23D998C565E8}\1.2\FLAGS]
@="0"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{814CC12B-836F-4898-8990-23D998C565E8}\1.2\FLAGS]
@="E:\Projects_MW\\MediawikiComIndex"

; ------------------------------------------------------------------------------

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\{B388036D-A4BB-4060-B5F1-9C5A0DE4D3E9}]
@="IMediawikiIndex"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\{B388036D-A4BB-4060-B5F1-9C5A0DE4D3E9}\ProxyStubClsid]
@="{00020424-0000-0000-C000-000000000046}"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\{B388036D-A4BB-4060-B5F1-9C5A0DE4D3E9}\ProxyStubClsid32]
@="{00020424-0000-0000-C000-000000000046}"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\{B388036D-A4BB-4060-B5F1-9C5A0DE4D3E9}\TypeLib]
@="{814CC12B-836F-4898-8990-23D998C565E8}"
"Version"="1.2"
</.reg file>

Rolf Lampa [RIL]

unread,
Jun 10, 2008, 10:23:12 AM6/10/08
to
Remy Lebeau (TeamB) skrev:

Except for the fact that the class don't gets instantiated properly (as it
seems) the Interface publishes the following methods, in this way (from the
_TLB.pas);

// *********************************************************************//
// Interface: IMediawikiIndex
// Flags: (256) OleAutomation
// GUID: {B388036D-A4BB-4060-B5F1-9C5A0DE4D3E9}
// *********************************************************************//
IMediawikiIndex = interface(IUnknown)
['{B388036D-A4BB-4060-B5F1-9C5A0DE4D3E9}']
function IndexByTitle(const aTitle: WideString): SYSINT; stdcall;
function Count: SYSINT; stdcall;
function IsInitialized: WordBool; stdcall;
function LoadIndexFromFile(const aFileName: WideString): WordBool; stdcall;
end;

Does any if these params or types look "malicious" for the registering mechanism
of the COM interfaces?

Regards,

// ROlf Lampa

Remy Lebeau (TeamB)

unread,
Jun 10, 2008, 1:55:03 PM6/10/08
to

"Rolf Lampa [RIL]" <rolf....@rilnet.will.do.fine.com> wrote in message
news:484e0611$1...@newsgroups.borland.com...

> Yes I have tried that, but it starts new instances, so the problem is the
> same.

That in itself suggests the server is not registered correctly. COM servers
that are in EXE files are supposed to be singletons. Only one instance of
the EXE is supposed to run at a time.

> This is insane, I start getting this creepy feeling about COM...

I ha never had these kind of problems with Borland's COM implementation.
I'm guessing something else is going on with your system to interfer with
it.


Gambit


Rolf Lampa [RIL]

unread,
Jun 11, 2008, 12:39:31 AM6/11/08
to
Remy Lebeau (TeamB) skrev:

Eventually... I reinstalled (repair-install) XP, and I forcefully run
(TTypedComObjectFactory).UpdateRegistry(True), then it started to play.

I also use ciSingleInstance for ClassInstancing, since ciInternal will cause the
Factory to skip registering the ClSID (see ComObj TComObjectFactory.UpdateRegistry).

== Singleton COM object ==

Now I only need to find a neat way to make my index to a Machine scope
Singleton, since the index it manages takes time to initialize (from disk) and
it occupies memory. I will use 4 clients on my 4CPU machine, but I really don't
want 4 instances of the Com Index...

So, in order to achieve a Singleton index I added an IIndexBroker class to the
Com Server, through which I can check if a unit variable (G_MediawikiIndex:
IMediawikiIndex) is assigned (create new Index only if = nil, etc).

However, I have no smart solution for how to dispose the Singeleton.

The problem is that the "self-referencing" MediawikiIndex-variable won't let the
RefCounter ever reach zero... and to solve this, all I could come up with on
the go, was an ugly hack where I (when I know I won't start more clients) ask
the IIndexBroker to also set the G_MediawikiIndex unit variable to nil (side
effect is that the singleton is no longer a singleton...). This will, however,
allow the singleton Index object to be discarded when all the clients are gone.
For my specific application I can avoid creating new instances, but a better
solution would be preferred, since in the future other requirements may arise.

Any ideas how to implement a smarter "true" singleton COM server object (.exe)?

Regards,

// Rolf Lampa

Jouni Aro

unread,
Jun 12, 2008, 4:28:06 PM6/12/08
to
Rolf Lampa [RIL] wrote:

> Any ideas how to implement a smarter "true" singleton COM server object
> (.exe)?

Hejsan Rolf :)

I think you need to create a special SingletonFactory which returns the
same instance to all clients. We used such a long time ago, in one
application, but it has been later been changed to "normal" style: there
is nowadays a standard singleton object, created when the app starts.
All the ComObjects created for the clients just refer the same "main
object".

Anyway, go and check the Tutorial of Binh Ly, at techvanguards.com - the
one about the factories is this:

http://www.techvanguards.com/com/concepts/serversandobjects.asp#Class%20Factory

BR,

Jouni

Rolf Lampa [RIL]

unread,
Jun 12, 2008, 5:25:34 PM6/12/08
to
Jouni Aro skrev:

> Rolf Lampa [RIL] wrote:
>
>> Any ideas how to implement a smarter "true" singleton COM server
>> object (.exe)?
>
> Hejsan Rolf :)

Terve! =)


> I think you need to create a special SingletonFactory which returns the
> same instance to all clients. We used such a long time ago, in one
> application, but it has been later been changed to "normal" style: there
> is nowadays a standard singleton object, created when the app starts.
> All the ComObjects created for the clients just refer the same "main
> object".
>
> Anyway, go and check the Tutorial of Binh Ly, at techvanguards.com - the
> one about the factories is this:
>
> http://www.techvanguards.com/com/concepts/serversandobjects.asp#Class%20Factory


Thank you for the hint! Yes, it seems like the problem should be solved at the
ClassFactory level.

Perhaps the best would be if there were a way to tweak the TypeLibrary editor to
auto generate a somewhat smarter class factory, that is, with an AsSingleton
property, not only the create method.

I never tried, but perhaps the shipped tlb-editor can be tweaked? If the source
code is shipped with D7 Ent, does anyone know it's name in the sources?

Regards,

// Rolf Lampa

Rolf Lampa [RIL]

unread,
Jun 12, 2008, 5:50:44 PM6/12/08
to
Rolf Lampa [RIL] skrev:
> Jouni Aro skrev:

>> Anyway, go and check the Tutorial of Binh Ly, at techvanguards.com -
>> the one about the factories is this:
>>
>> http://www.techvanguards.com/com/concepts/serversandobjects.asp#Class%20Factory
>
>
> Thank you for the hint! Yes, it seems like the problem should be solved
> at the ClassFactory level.
>
> Perhaps the best would be if there were a way to tweak the TypeLibrary
> editor to auto generate a somewhat smarter class factory, that is, with
> an AsSingleton property, not only the create method.

... or simply subclass the TTypedComObjectFactory class into
"TTypedComSingletonObjectFactory" and call that one instead, since the code
calling the factory.create is not affected by subsequent changes to the
interfaces done using the tlb-editor.

Regards,

// Rolf Lampa

Jouni Aro

unread,
Jun 13, 2008, 1:41:44 AM6/13/08
to

Yes, that's the way to go, I think.

The type library and tlb editor are not that easily customizable,
according to what I remember.

BR, Jouni

0 new messages