2008. április 20., vasárnap

Distributable COM Objects on Remote Machines


Distributable COM Objects on Remote Machines


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.

function CreateRemoteComObject(const MachineName: WideString;
                               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.

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.

uses ComObj;

// GUID of my test object ‘serv.server’
  PUNK: TGUID = '{74A5EC07-DC84-4C65-8944-1A2315A550FB}';

procedure TForm1.Button1Click(Sender: TObject);
  Ole: OleVariant;
  BDate: WideString;
  // Create the object as IDISPATCH
  Ole := CreateRemoteComObject('mheydon', PUNK) as IDispatch;

  Ole.BirthDate(46, BDate); // Method of 'serv.server'

  Ole := VarNull; // Free object and deactivate

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 ?

Nincsenek megjegyzések:

Megjegyzés küldése