Problem/Question/Abstract:
Distributable COM Objects on Remote Machines
Answer:
There is not much documentation around on DCOM. DCOM is similar to COM except that
the objects reside and are registered on remote machines.
In this article I demonstrate how to connect to and execute remote COM objects
(your own or 3rd party). The objects must support the IDISPATCH interface (majority
do).
Those of you familiar with the function CreateOleObject() will be quite comfortable
with the approach, others can search the Internet for "COM" articles to clarify
this technique.
The Windows DCOMCNFG.EXE, which allows permission and properties to be maintained
by the remote machine is also discussed.
The article was written using platforms Delphi 5 and Win2000. I do not know if this
approach works on lesser versions as I do not have access to them..
The function commonly used to connect to COM/OLE objects is CreateOleObject().
eg. Ole := CreateOleObject(‘word.application’);
The connection to a DCOM object is not that different in concept except that we use
the GUID of the object class instead of the Classname string, CreateComObject()
also uses the GUID.
The function we use to implement DCOM in Delphi is CreateRemoteComObject(), which
resides in unit ComObj.
Definition
1 function CreateRemoteComObject(const MachineName: WideString;
2 const ClassID: TGUID): IUnknown;
The MachineName is a string of the Target machine that you want to run the Object
on.
eg. ‘mheydon’
The ClassID is the GUID of the object that is found in the registry under key
HKEY_LOCAL_MACHINE\Software\CLSID.
3 4 eg. const PUNK : TGUID = '{000209FF-0000-0000-C000-000000000046}';
Refer to my article “COM/OLE Object Name Utility Procedure ” for an easy way to
browse for these GUIDs
The function (if successful) returns an IUNKNOWN interface. We require an IDISPATCH
interface, thus we will simply use Delphi’s typecasting feature.
A trivial example of a user written COM/OLE application is as follows. The method
BirthDate() simply returns a string containing the birthdate of the given age in
years from the target machine.
5 uses ComObj;
6 7 // GUID of my test object ‘serv.server’8 const9 PUNK: TGUID = '{74A5EC07-DC84-4C65-8944-1A2315A550FB}';
10 11 procedure TForm1.Button1Click(Sender: TObject);
12 var13 Ole: OleVariant;
14 BDate: WideString;
15 begin16 // Create the object as IDISPATCH17 Ole := CreateRemoteComObject('mheydon', PUNK) as IDispatch;
18 19 Ole.BirthDate(46, BDate); // Method of 'serv.server'20 showmessage(BDate);
21 22 Ole := VarNull; // Free object and deactivate23 end;
As you can see it is a very simplified example (without error checking), but the
prime objective was to display the DCOM connectivity in a clear way.
The other thing that affects the DCOM object on the target machine is permissions
and other properties. If you are getting “Access Denied” or want to change the
behaviour of the remote object then run the Windows utility DCOMCNFG.EXE. This has
many options and a summary is as follows.
Main form. Select your object here and set it’s properties. Be careful if playing
with any of the DEFAULT tabs as they will affect ALL your objects.
General. All you change here is Authentication level. Not sure what affects all the
different options have.
Location. Where to run the application.
Security. If you are getting Access Denied errors when connecting then you can
modify or add users here.
Identity. This is similar to setting the user of a Windows Service. If you want to
be able to kill the process from task manager then you should set this option to
“This users” where the user is the current user of the machine, or else task
manager will tell you that you have no permissions to kill the process.
Endpoints. Have absolutely no idea what this page does. Some light anyone ?