DCOM, Automated COM, and Headaches

I need to create an automated COM object in Delphi 5, which can be called via DCOM from another machine. I can't use type libraries but have figured out HOW to actually link to the object remotely (CreateRemoteCOMObject) and how to use the methods stored within it. I've copied the object AND my test application (that calls it) onto both machines, registered the object in the Registry and it don't want to work. It will work locally with no problem (still using CreateRemoteCOMObject and setting the machine name to be my own) but try getting to it from somewhere else and it's a bad case of Class Not Registered. Will someone be good enough to point out just how stupid I am at not being able to get this to work
LVL 5
TheNeilAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

schutnikCommented:
What do you mean you can't use type libraries?

First of all, the COM CLSID must be registered on both machines with the associated TypeLib key (should point to a valid registered TypeLib for the class).

Second of all, the application must be running as a user that has rights to the DCOM server host (if it is NT/2000).

Access denied is the message you will receive if the second condition is not met, class not registered is the message for the first condition.

Kelly
0
rajeshveeCommented:
Dont' forget to set the priveleges by running DCOMCNFG at the server.
0
TheNeilAuthor Commented:
I've checked DCOMCNFG but the object doesn't appear in the list of Applications.

Can't use Type Libraries as this is part of a huge system with COM objects coming in from a load of different systems and I can't make the assumption that a type library is available (real pain but that's he way it is).

Oh, and this is running on a purely NT network - no nasty 95/98 to screw it all up

Anyone who figures out the problem of HOW to get the COM object to register itself in the list of applications in DCOMCNFG (and tells the rest of the world), gets the points

The Neil
0
Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

schutnikCommented:
To register the COM object in DCOMCNFG (not sure this will fix your problem, however) all you have to do is create an AppID under the Appid key in HKEY_CLASSES_ROOT, specify that AppID in a REG_SZ value under the CLSID registration and voila, there it is in DCOMCNFG.

(You might want to put a name in the AppID key's default value so you know what you're looking at!)

If you are calling the objects through IDispatch, then you're right, you don't need typeLibs, so you can disregard my previous answer.

Kelly
0
TheNeilAuthor Commented:
It's first day back after Christmas and New Year so my brain is a little fuzzy today so...

What's a REG_SZ value, where do I get one, and do they come in a range of colours?

I have some sample code from Delphi 4 Unleashed (I'm using 5 but what the hell) that demonstrates the whole thing and it doesn't need registering manually so I'm pretty certain that your solution might fix the registration in DCOMCNFG but won't fix my problem.

Thanx anyway

The Neil
0
nrobinCommented:
TheNeil,

Once you move your object into the DCOM domain, you first hit a number of problems regarding security.  On the client machine, you can create an AppID which has the GUID of your main COM object that you are creating.  in the AppID\<your GUID> you can add a new value of type string called RemoteServerName - the value being the IP or name of the remote machine - this provides part of the users location/access transparency.

However, one of your other big problems is that you do not use a typelibrary.  If you do not provide a typelibrary, you *must* provide your own way of dealing with something called Method Remoting and Marshaling.  

To keep things simple, and to get things working, I suggest doing the following:

1. Create a new COM server with typelibrary
2. Put on second machine
3. Try to instance the new COM server

Remember you must register the COM server on both machines for safety.  

The next problem is what platform the OS is that hosts the COM server.  Win95 machines cannot instance the COM server via access from a remote client, so it must already be running before you try to access it.  NT has more stringent ssecurity access/control mechanisms in place, and I would suggest taking a look at:

http://www.distribucon.com 

HTH

Nick.



0
TheNeilAuthor Commented:
All machines in this little instance are NT 4 and security is not a problem (Access rights are fine).

The solution was given to me by a colleague and it turns out that DCOMCNFG has a few little quirks that meant that it wasn't registering DCOM objects properly.

Anybody who gives me their credit card details (joke) as an answer can have the points.

The Neil
0
nrobinCommented:
You will still get some problems unless you provide a marshaling proxy/stub dll since you are not using the typelibrary....

Nick.
0
schutnikCommented:
You don't need the type library unless you try to make non-IDispatch calls.

He's (TheNiel) right about that.

DCOM will allow marshalling of calls over process & machine boundaries if the interface requested is IDispatch (with no special marshalling or proxy stuff).  It is only if you want to do early binding to the component that you need the type library.

I use late binding quite often from C++ programs (for utilities & the like that use a com object & method specified by name).  I never NEED to register a typelib for these components.  It simply makes coding easier if the typelib is registered (so that I can use Intellitype & other such features like the object browser).

If the typelib was required, then Windows Scripting Host & ASP would never work against MTS and remote objects.  Basically, the only reason you would need a typelib is if you ask for a custom interface by iid (not IDispatch or IUnknown) because the Win32 proxy-stub implementation has to know the details about the interface you're asking for.  These are system defined interfaces, so it already knows them without looking in your typelib (as a matter of fact, the proxy-stub implementation would never even look in your typelib for a direct call to IUnknown or IDispatch).

Glad you got it working
Kelly
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
schutnikCommented:
By the way, a REG_SZ value is a string value in Regedt32 terms.

Kelly
0
nrobinCommented:
Fair comment Kelly - TheNeil never mentioned that he was specifically only using IDispatch - hence the requirement for typelibrary marshaling.  TheNeil never mentioned the binding option chosen, nor that custom interfaces arent being used - hence he needs to know that there could be a problem.  Late binding obviously doesnt require the typelibrary at least on the client - but it is required on the server.

The proxy-stub marshaling for said IUnknown and IDispatch takes place via the standard marshaler which is part of COM/OLE.

Nick.
0
schutnikCommented:
Actually, the typelib does not have to be registered on the server either.

(It generally is, but it doesn't have to be)

The reason it doesn't have to be is that the typelib information is included in the .DLL and the .DLL will load the typelib automatically when it creates the object (or when it initializes the .DLL depending on the way it is coded).  Remember, the IDispatch::Invoke calls are handled by the object itself, not the ITypeInfo interface (although ITypeInfo provides the standard implementation).  ITypeInfo can be obtained from ITypeLib which in turn is obtained from the LoadTypeLib() API function, which doesn't require the typelib to be registered.

Kelly
0
nrobinCommented:
Ok, but have you seen this?

Nick.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.