お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"DCOM(Remote Automation)をやる"



 なんだかよくわからないものの筆頭である DCOM をやってみました.


1.用意したもの
 Delphi3.1J Pro版   C/S版は要りません
 WindowsNT4.0(SP3)  サーバ(95でもできるらしい)
  Windows95          クライアント.OSR2でなくてもよい
 95用DCOMモジュールをwww.microsoft.com/japanから拾ってくる
 マシン同士はTCP/IPでつないである.

2.下準備
・ クライアントの95にDCOMをインストールする.既に入っていれば不要.
<レジストリの確認>
  HKEY_LOCAL_MACHINE
    SOFTWARE
      Microsoft
        OLE
            EnableDCOM = "Y"
            EnableRemoteConnection = "Y"

・ サーバにするNTのRPC Service,DCOMを有効にする
<レジストリの確認>
  HKEY_LOCAL_MACHINE
    SOFTWARE
      Microsoft
        OLE
            EnableDCOM = "Y"
            EnableRemoteConnection = "Y"

 Dcomcnfg.exeを使う.なんか動きがいまいちだけど(-_-;)

3.DCOMサーバアプリケーションの作成
・普通にアプリケーションの新規作成をする
・オートメーションオブジェクトの新規作成をする
・タイプライブラリエディタが出てくるので,適当にメソッドの宣言を
 作り,更新ボタンを押すとXXXX_TLB.pasとUnit2.pasが出来る.
・下記の例のようにサーバとなるクラス(IMyServerはIDispatchの派生)の
 中身を詰め込む.
・コンパイルしてサーバとクライアント両方のマシン上で一回実行して
 レジストリにオブジェクトの情報を登録させる
・IDispatch(OLEAutomation)に関する引数の型の制限に注意.
・クライアントが誰でも実行できるようにするには,Dcomcnfg.exeでセキュリ
 ティの設定をしただけでは駄目.サーバの実行をAdministratorsグループの
 ユーザーに決めておくと,できる.
・ciMultiInstanceの場合,上記の場合サーバプロセスはひとつだけ起動する.
 複数のマシンから別々のアカウントでログインしてもサーバプロセスは1個.
 一方TMyServerのインスタンスは,Create要求の数だけ生成される.
・ciSingleInstanceだと,クライアントアプリのインスタンスごとに
  それぞれサーバが立ち上がるのをタスクマネージャで見れる.
・コンパネ/サービス/RPC Serviceをダブルクリックして「デスクトップとの
 対話」を許可しておくと,サーバが走っている間はサーバマシンの画面に
 サーバーアプリのフォームが現れ,さわることが可能になる.
・念のため NT をリブート.
・スレッドがどうのこうのというのはまだ意味不明...
--------------------------------------------------------------------------
unit unit1
 省略 Editを一個貼り付けておく
--------------------------------------------------------------------------
unit Unit2;

interface

uses
  Windows, SysUtils, ComObj, ActiveX, MyServerPrj_TLB, Forms;

type
  TMyServer = class(TAutoObject, IMyServer)
  protected
    procedure Beep; safecall;
    procedure GetText(out S: WideString); safecall;
  end;

implementation

uses ComServ, Unit1;

var
  Count: integer;

procedure TMyServer.Beep;
begin
  MessageBeep(0);
end;

procedure TMyServer.GetText(out S: WideString);
begin
  inc(Count);
  S := InttoStr(Count) + ' time(s) of GetText.' + Form1.Edit1.Text;
end;

initialization
  TAutoObjectFactory.Create(
    ComServer, TMyServer, Class_MyServer, ciMultiInstance);
end.
------------------------------------------------------------------------
unit MyServerPrj_TLB;
 省略
------------------------------------------------------------------------

4.クライアントアプリケーションの作成
・普通にアプリケーションの新規作成をする.
・サーバで使っているXXXX_TLBユニットをusesして新しいインターフェース
 宣言を取り込み,下記のようにDCOMオブジェクトの生成とメソッド呼出をする
・できたクライアントアプリをクライアントマシンで実行する.
-----------------------------------------------------------------------
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComObj, StdCtrls, MyServerPrj_TLB;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Edit1: TEdit;     // DCOMサーバを走らせるコンピュータ名を書き込む
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    Obj: IUnknown;    // クライアントを閉じるまでオブジェクトを保持
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
  S: WideString;
  Intf: IMyServer;
begin
  if Obj = nil then begin
    Obj := CreateRemoteComObject( Edit1.Text,
                                ProgIDToClassID('MyServerPrj.MyServer') );
  end;
  Intf := Obj as IMyServer;
  Intf.Beep;        // サーバのマシンでBeep音が鳴る!!
  Intf.GetText(S);  // ボタンを押した回数がサーバに蓄えられている
  Label1.Caption := S;
end;

end.
--------------------------------------------------------------------------

5.余談
 IDispatchでないとクライアントでInterfaceが取得できないというのは
なにか忘れているせいだと思うが,C/Sに付いてるClientDataSetコンポで使う
IProviderもIDispatchの派生にしてある所を見ると理由があるのだろう.
 参考書には肝心なこと(最低何と何をすればDCOMできるのか?)がさっぱり
書いてないのでほとんど無意味(-_-;

「DCOMデプロイメントガイド」翔泳社
「DCOMガイドブック」オーム社

                                                  TN(CQJ01721)

Original document by TN            氏 ID:(CQJ01721)


ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum