Exchange 2000徹底解剖
>
開発環境としてのExchange 2000 Server
|
引き続き,Event SinkをサポートするCOMコンポーネントをどのように作ればよいのかについて説明する。
ここでは,同期イベントのOnSyncSaveイベントを利用し,(1)10Kバイト以上のアイテムが保存されたときにはAdministrator宛にメールを送信する,(2)20Kバイト以上のアイテムは保存できないようにする,というイベント処理をするCOMコンポーネントをVisual Basic 6.0を用いて作ってみることにする。
あるサイズ以上の大きさなアイテムが保存されようとしたときに管理者に警告したり,保存を拒否したりという設定は,Exchange 2000 Serverのストアやフォルダのプロパティの[制限]ページで設定することができる。そのため,単にこれだけの目的であれば,実際にEvent Sinkを使ってプログラムを開発する必要性はない。
●プロジェクトの作成と参照設定
Event Sinkのイベントを処理するCOMコンポーネントは,ActiveX DLLの形式で作成する。そこで,Visual Basicを起動したのち,[ActiveX DLL]を選択してプロジェクトを新規作成することになる(Fig.2-23)。
Event Sinkに対応したCOMコンポーネントを開発するためには,「EXOLEDB Internal Type Library」の参照設定が必要となる。そこで,開発にあたっては[プロジェクト]メニューの[参照設定]を選択し,[EXOLEDB Internal Type Library]を参照設定しておく(Fig.2-24)。
参照設定すべきものは[EXOLEDB Internal Type Library]だけでよいのだが,実際にはADOコンポーネントやCDOコンポーネントを使ってアイテムにアクセスすることになるから,それ以外にも,一般に[Microsoft ActiveX Data Objects 2.5 Library]や[Microsoft CDO for Microsoft Exchange Library]の参照設定が必要になってくる。今回のサンプルでも,ADOコンポーネントを使ってアイテムにアクセスし,CDOコンポーネントを使ってメールを送信するため,これらの参照設定が必要となる。
Fig.2-23 ActiveX DLLの新規作成(図版をクリックすると拡大可能)

Fig.2-24 EXOLEDB Internal Type Libraryの参照設定(図版をクリックすると拡大可能)

プロジェクトの設定を終えたら,実際にソースを記述してゆく。今回作成するプログラムは,List 14のようになる。
Event Sinkに対応したCOMコンポーネントは,まず1行目にあるようにImplementsキーワードを使ってイベントに対応するインタフェースを実装し,3行目や41行目にあるように“インタフェース名_イベント名”というプロシージャ内に実際の操作内容を記述するというスタイルになる。Event Sinkが対応するインタフェースやイベント名は,Table 9の通りである。List 14では,アイテムが保存されようとしているときのイベントを処理したいので,IExStoreSyncEventsインタフェースを実装している。
List 14の場合,3〜39行目が同期イベントのOnSyncSaveイベント(すなわち,アイテムが保存されようとしているときのイベント)を処理する箇所となる。3行目にあるように,OnSyncSaveイベントは次の書式をとる。
Private Sub IExStoreSyncEvents_OnSyncSave( _ ByVal pEventInfo As Exoledb.IExStoreEventInfo, _ ByVal bstrURLItem As String, _ ByVal lFlags As Long)
lFlags引数には,呼び出されたときの状況が格納される。格納される値は,Fig.2-22で説明したEVT_SYNC_BEGINフラグやEVT_SYNC_COMITTEDフラグなどの組み合わせである。lFlags引数はTable 10に示す値の組み合わせ(和)をとる。List 14では,13行目にあるようにEVT_SYNC_BEGINフラグが設定されていたとき――つまり,アイテムが保存されようとしているとき――に,そのアイテムのサイズを調べるという処理にしてある。
保存しようとしているアイテムは,pEventInfo引数を通じて取得できる。pEventInfo引数を通じて取得するためには,10行目にあるように,まずpEventInfo引数の値をIExStoreDispEventInfoインタフェースとして宣言した任意の変数に格納する。IExStoreDispEventInfoインタフェースは,Table 11に示すメソッドやプロパティを備えている。このうち,EventRecordプロパティには,アイテムのプロパティ情報を示すADODB.Recordオブジェクトが格納されていて,それを通じてアイテムの全プロパティを取得できる。プロパティを取得するには,19行目にあるように,ADODB.RecordオブジェクトのFieldsコレクションを利用すればよい。
List 14においては,DAVネームスペースのgetcontentlengthプロパティを参照し,保存されようとしているアイテムのバイト数が10Kバイト以上のときにはAdministrator宛にメールを送信し(20〜30行目),20Kバイト以上のときには保存させないようにしている(31〜34行目)。20〜30行目の処理は,CDOコンポーネントを使ってメールを送信しているだけなので,ここでの説明は省く。
31〜34行目の処理では,アイテムを保存させないようにしている。そのためには,33行目にあるようにAbortChangeメソッドを呼び出す。すると,アイテムが保存されなくなる。
ただし,アイテムが保存されなくなるといっても,アイテムを保存しようとしているクライアントに対して何らかのエラーが戻るわけではない。たとえば,List 14のCOMコンポーネントが設定されたフォルダに対して20Kバイト以上のアイテムを保存しても,クライアントにはエラーは戻らない。しかし,エラーは発生しなくても,アイテムは保存されない。また,このときイベントログには,Fig.2-25に示すメッセージが残る。
List 14では,getcontentlengthプロパティを参照しているだけであり,アイテムの本文を参照したり書き換えたりしているわけではない。その点では,比較的簡単なプログラムといえる。もし,アイテムの本文の内容によって処理を分岐させたり,アイテムの本文を書き換えたりしたいのであれば,IExStoreDispEventInfoインタフェースのDataプロパティを用いて,アイテムに対して操作することになる。
| インタフェース | イベント名 | 解説 |
|---|---|---|
| IExStoreSyncEvents | OnSyncDelete | 削除されようとしているとき |
| IExStoreSyncEvents | OnSyncSave | 保存されようとしているとき |
| IExStoreAsyncEvents | OnDelete | 削除されたとき |
| IExStoreAsyncEvents | OnSave | 保存されたとき |
| ICreateRegistration | Register | COMコンポーネントがEvent Sinkに登録されようとしているとき |
| IExStoreSystemEvents | OnTimer | 一定時間が経過したとき |
| IExStoreSystemEvents | OnMDBStartUp | ストアが起動したとき |
| IExStoreSystemEvents | OnMDBShutdown | ストアが終了しようとしているとき |
Table 10 OnSyncSaveイベントのlFlags引数の取り得る値
| 定数 | 解説 |
|---|---|
| EVT_NEW_ITEM | 新しいアイテムである |
| EVT_IS_COLLECTION | アイテムはコレクション(ディレクトリ)である |
| EVT_REPLICATED_ITEM | レプリケーションの結果作られたアイテムである |
| EVT_IS_DELIVERED | メッセージとして届けられたアイテム(メールなど)である |
| EVT_INITNEW | 1つのEvent Sinkに対して,それぞれ初めてOnSyncSaveイベントが発生したときに設定される |
| EVT_MOVE | アイテムは移動されようとしている |
| EVT_COPY | アイテムはコピーされようとしている |
| EVT_DRAFT_CREATE | アイテムは下書きである |
| EVT_DRAFT_SAVE | 下書きが保存されたアイテムである |
| EVT_DRAFT_CHECKIN | 下書きがチェックインされたアイテムである |
| EVT_SYNC_BEGIN | OnSyncSaveイベントの始まりを示す |
| EVT_SYNC_COMMITED | OnSyncSaveイベントの完了を示す |
| EVT_SYNC_ABORTED | OnSyncSaveイベントの処理中にAbortChangeメソッドが呼び出されて中断されたことを示す |
| EVT_INVALID_SOURCE_URL | コピーや移動もとのURLが正しくないことを示す |
| EVT_INVALID_URL | 保存先のURLが正しくないことを示す |
| EVT_ERROR | その他のエラーが発生していることを示す |
Table 11 IExStoreDispEventInfoインタフェースに備わるメソッドならびにプロパティ
| メソッド | 解説 |
|---|---|
| AbortChange | 保存や削除を中止する |
| EventBinding | イベントをオブジェクトに対してバインドする |
| プロパティ | 解説 |
| EventConnection | ADODB.Connectionオブジェクトを得る |
| EventRecord | ADODB.Recordオブジェクトを得る |
| SourceURL | 移動やコピー,削除もとのURL |
| UserGuid | ユーザーのGUID |
| StoreGUID | 保存先ストアのGUID |
| UserSid | ユーザーのSID |
| Data | アイテムのデータ |
Fig.2-25 保存を中止したときのイベントログ(図版をクリックすると拡大可能)

| 24/27 |
