Exchange 2000徹底解剖
開発環境としてのExchange 2000 Server

Event Sinkを使ったプログラムの例

 引き続き,Event SinkをサポートするCOMコンポーネントをどのように作ればよいのかについて説明する。

 ここでは,同期イベントのOnSyncSaveイベントを利用し,(1)10Kバイト以上のアイテムが保存されたときにはAdministrator宛にメールを送信する,(2)20Kバイト以上のアイテムは保存できないようにする,というイベント処理をするCOMコンポーネントをVisual Basic 6.0を用いて作ってみることにする。


One Point! あるサイズ以上の大きさなアイテムが保存されようとしたときに管理者に警告したり,保存を拒否したりという設定は,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_23

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

●プログラムの開発
 プロジェクトの設定を終えたら,実際にソースを記述してゆく。今回作成するプログラムは,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プロパティを用いて,アイテムに対して操作することになる。

Table 9 インタフェースとイベント名

インタフェースイベント名解説
IExStoreSyncEventsOnSyncDelete削除されようとしているとき
IExStoreSyncEventsOnSyncSave保存されようとしているとき
IExStoreAsyncEventsOnDelete削除されたとき
IExStoreAsyncEventsOnSave保存されたとき
ICreateRegistrationRegisterCOMコンポーネントがEvent Sinkに登録されようとしているとき
IExStoreSystemEventsOnTimer一定時間が経過したとき
IExStoreSystemEventsOnMDBStartUpストアが起動したとき
IExStoreSystemEventsOnMDBShutdownストアが終了しようとしているとき

Table 10 OnSyncSaveイベントのlFlags引数の取り得る値

定数解説
EVT_NEW_ITEM新しいアイテムである
EVT_IS_COLLECTIONアイテムはコレクション(ディレクトリ)である
EVT_REPLICATED_ITEMレプリケーションの結果作られたアイテムである
EVT_IS_DELIVEREDメッセージとして届けられたアイテム(メールなど)である
EVT_INITNEW1つのEvent Sinkに対して,それぞれ初めてOnSyncSaveイベントが発生したときに設定される
EVT_MOVEアイテムは移動されようとしている
EVT_COPYアイテムはコピーされようとしている
EVT_DRAFT_CREATEアイテムは下書きである
EVT_DRAFT_SAVE下書きが保存されたアイテムである
EVT_DRAFT_CHECKIN下書きがチェックインされたアイテムである
EVT_SYNC_BEGINOnSyncSaveイベントの始まりを示す
EVT_SYNC_COMMITEDOnSyncSaveイベントの完了を示す
EVT_SYNC_ABORTEDOnSyncSaveイベントの処理中にAbortChangeメソッドが呼び出されて中断されたことを示す
EVT_INVALID_SOURCE_URLコピーや移動もとのURLが正しくないことを示す
EVT_INVALID_URL保存先のURLが正しくないことを示す
EVT_ERRORその他のエラーが発生していることを示す

Table 11 IExStoreDispEventInfoインタフェースに備わるメソッドならびにプロパティ

メソッド解説
AbortChange保存や削除を中止する
EventBindingイベントをオブジェクトに対してバインドする
プロパティ解説
EventConnectionADODB.Connectionオブジェクトを得る
EventRecordADODB.Recordオブジェクトを得る
SourceURL移動やコピー,削除もとのURL
UserGuidユーザーのGUID
StoreGUID保存先ストアのGUID
UserSidユーザーのSID
Dataアイテムのデータ

Fig.2-25 保存を中止したときのイベントログ(図版をクリックすると拡大可能)
fig_25

Prev 24/27 Next