2006年03月12日

COM クライアント実装の道程 for TaskScheduler その6

死亡フラグって言いますよね。「この戦争が終わったら、俺、結婚するんだ」とか言うの。これ、死にフラグって表現もあると言うことを最近知りました。しかし死にフラグってのは、まるで上げ下げはしてるんだけどだれもそのフラグを参照してない孤独なフラグってイメージが。いやどうでも良いんですが。

今回から Task と TaskTrigger の解説に入るわけですが、いきなりクラスの解説をし出しても理解しにくいでしょうから、まずその下準備として ITask インターフェイスを中心にタスクアイテムの構造を述べていくことにします。

と切り出しておいて何ですが、実のところタスクアイテムの構成ってのはタスクのプロパティダイアログに表示されている奴ほぼそのままなんですよね。

ここから先は Windows XP を使って解説しているので、他の OS だと見え方が違うかもしれません。

まずタスクアイテムとは、コントロールパネルからタスクフォルダを開けたときに見えるそれぞれのアイテムを指します。このアイテムの実体は、プロパティダイアログのタスクタブ、アイコンの横に書かれているパスにあるファイルです。

タスクアイテムは一つで一つだけプログラムを起動させることが可能です。同一の条件で複数のプログラムを起動させたい場合は、複数のタスクアイテムを用意するか、その起動させたいプログラム群を bat ファイルにでも書いてそれを起動させることになります。指定したものが実行ファイルでなかった場合、関連づけに従って対応するアプリケーションが起動します。

NT 系では、起動させるユーザを指定する必要があります。その場合当然ながらそのユーザのパスワードも必要となります。そのユーザがログオンしていなくてもそのタスクは実行されます。ただし、そのユーザがログオンしているときだけ有効とした場合はパスワードが不要になります。

タスクアイテムは単一または複数のトリガを持つことができます。トリガとは、そのタスクアイテムのプログラムを起動させるための条件のことを指します。トリガには何日かごとなのか一回だけなのか、何時に開始するのかと言った情報を持ちます。トリガの有効期間や、あるいはそのトリガで起動したプログラムの自動終了時間なども設定できます。

タスクアイテム全体としても自動終了時間を持つことができます。他にもいくつか設定できる項目がありますが、ダイアログそのままなので省略。

以上のことを実現するために、タスクアイテムを ITask インターフェイスで表現しこれらにタスクアイテムに直接作用する情報を設定させ、トリガに関しては ITaskTrigger インターフェイスを使って複数のトリガを受け取れるようにします。

トリガは ITask から見た場合は ITaskTrigger インターフェイスですが、自身に直接情報を設定するメソッドを公開している ITask と違って、トリガの情報の実体は TASK_TRIGGER 構造体に存在します。

これらによってタスクスケジューラは大変に多機能ですが、多機能は複雑さを生み出します。ITask インターフェイスも TASK_TRIGGER 構造体もややこしいこと甚だしい。そこで、今回はこれをいかにばらすかを考えていきましょう。

まずは ITask インターフェイスから、手始めにインターフェイスのメソッドを列挙してみましょう。Get と Set のペアメソッドは一つの項目で説明します。

メソッド名説明
CreateTrigger タスクの実行開始トリガを新しく作成します。
DeleteTrigger 指定したインデックスのトリガを削除します。
SetTriggerCountこのタスクアイテムが持っている、タスク起動トリガの数を取得します。
GetTrigger 指定したインデックスのトリガを取得します。
GetTriggerString トリガの文字列表現を取得します。
GetRunTimes タスクが起動する日時の配列を取得します。
GetNextRunTime 次回タスクが起動する時間を取得します。
Get/SetIdleWait タスクが起動される前に必要なアイドル時間を取得または設定します。
Run タスクアイテムが指定しているプログラムの開始をタスクスケジューラに要求します。
Terminate 現在実行中のタスクアイテムが起動したプログラムを終了させます。
EditWorkItem タスクアイテムのプロパティダイアログを開きます。
GetMostRecentRunTime 直近に実行された日時を取得します。
GetStatus タスクアイテムの状態を取得します。
GetExitCode 最後に実行されたタスクの終了コードを取得します。
Get/SetComment タスクアイテムにコメントを取得または設定します。
Get/SetCreator タスクアイテムの作成者を取得または設定します。
Get/SetWorkItemData タスクアイテムに、アプリケーション定義のデータを取得または設定します。
Get/SetErrorRetryCount タスクアイテムの起動に失敗した際に、タスクスケジューラが試みるリトライの回数を取得または設定します。現在は未実装です。
Get/SetErrorRetryInterval タスクの起動に失敗した際に、タスクスケジューラがリトライを実行するまでの間隔を取得または設定します。現在は未実装です。
Get/SetFlags タスクアイテムに関するフラグを取得または設定します。
Get/SetAccountInformation タスクアイテムが実行するアカウントを取得または設定します。
Get/SetApplicationName タスクアイテムが実行するファイル名を取得または設定します。
Get/SetParameters タスクアイテムが実行するときに使用するコマンドライン引数を取得または設定します。
Get/SetWorkingDirectory タスクアイテムが実行するときの起動ディレクトリを取得または設定します。
Get/SetPriority 実行するタスクの優先度を取得または設定します。
Get/SetTaskFlags タスクの振る舞いを変更するフラグを取得または設定します。現在はサポートしているフラグはありません。
Get/SetMaxRunTime 実行しているタスクを終了させるまでの最大時間を取得または設定します。

なかなか大した数ですが、順番に考えていきましょう。まず、単純に値を設定・取得すれば良いもの。プロパティにすべきものですね。

  • Get/SetApplicationName
  • Get/SetParameters
  • GetNextRunTime
  • Get/SetWorkingDirectory
  • GetMostRecentRunTime
  • Get/SetPriority
  • Get/SetMaxRunTime
  • GetTriggerCount
  • Get/SetIdleWait
  • GetStatus
  • Get/SetComment
  • Get/SetCreator
  • Get/SetFlags
  • Get/SetWorkItemData
  • Get/SetErrorRetryCount
  • Get/SetErrorRetryInterval
  • Get/SetTaskFlags

この辺が候補に挙げられます。このうち、GetNextRuntime と GetMostRecentRunTime は微妙です。値を持っていない可能性があるからです。.NET 2.0 では Nullable で問題ないですが、それ以前のバージョンのことも考えるなら、ここはメソッドにして同時に TryGet... も用意するというのが考えられます。また、下3つに関しては、どうせサポートしていないし現状対応できるものでもないので、切り捨てることにします。ほかに Get/Set のペアになっているメソッドは Get/SetAccountInformation がありますが、これは引数の数が違う( Get はアカウント名のみ、Set にはパスワードも必要)のでプロパティにするには向いていません。

残りのメソッドはざっと見、特に問題なさそうですが、トリガとの関連は考慮しておくべきでしょう。トリガは ITask からは ITaskTrigger を介して取得・設定します。その ITaskTrigger 自体は、TASK_TRIGGER に対する Get/Set 、あとは自身の情報を文字列で表現する GetTriggerString の三つしかメソッドを持っていません(しかもこれは ITask.GetTriggerString で代用できます)。また、ITask がトリガに関わるのは CreateTrigger、DeleteTrigger、GetTrigger、GetTriggerString の四つのメソッドにおいてですが、このうち ITaskTrigger を使うのは CreateTrigger と GetTrigger のみ。CreateTrigger の一般的な手順は以下の通りです。

  1. ITask.CreateTrigger で ITaskTrigger 取得
  2. ITaskTrigger.SetTrigger で TASK_TRIGGER を設定
  3. ITask からキャストした IPersistFile.Save で保存

となるとわざわざこの ITaskTrigger をユーザに見せる必要性は無いように思えます。むしろ公開すべきなのは TASK_TRIGGER 構造体の方です。トリガを作る際は、必要な情報をそろえた構造体を受け取って上記の三手順を一気にやっちゃえばいいでしょう。

と、今回は説明だけ。次回は Task のいくつかの実装を紹介しましょう(わざわざ書く必要がないのも多いですし。文字列の取得・設定メソッドとか)。

posted by Hongliang at 17:38| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック

ここ(hongliang.seesaa.net)で公開しているものについて、利用は自由に行って頂いて構いません。改変、再頒布もお好きになさって下さい。利用に対しこちらが何かを要求することはありません。

ただし、公開するものを使用、または参考したことによって何らかの損害等が生じた場合でも、私はいかなる責任も負いません。

あ、こんなのに使ったってコメントを頂ければ嬉しいです。

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。