2010年11月2日火曜日

JvScheduledEventsを試してみる。

仕事で、とあるプロセスを定刻起動する必要があった。

OS標準のタスクスケジューラを使用してもよっかったが
起動できるのがバッチファイルか単独のEXEになるので
もううちょっと処理を柔軟にしたいと思いJVCLの
JvScheduledEventsを試してみた。

TJvScheduledEventsは、画面でスケジューリングの
設定が可能であるが、今回は、スケジュールを外部
ファイルに持たせたかったので、プラグラム中で
設定することにした。

以下、サンプルで試したソース。

  1. unit Unit1;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  7.   Dialogs, JvScheduledEvents, StdCtrls, ExtCtrls, ComCtrls, JvComponentBase,  
  8.   JvCreateProcess;  
  9.   
  10. type  
  11.   TForm1 = class(TForm)  
  12.     Button1: TButton;  
  13.     DateTimePicker1: TDateTimePicker;  
  14.     Label1: TLabel;  
  15.     LabeledEdit1: TLabeledEdit;  
  16.   
  17.     procedure FormCreate(Sender: TObject);  
  18.     procedure FormDestroy(Sender: TObject);  
  19.     procedure Button1Click(Sender: TObject);  
  20.   private  
  21.     { Private 宣言 }  
  22.     FJvScheduledEvents : TJvScheduledEvents;  
  23.     procedure JvScheduledEventsExecute(Sender: TJvEventCollectionItem;  
  24.               const IsSnoozeEvent: Boolean);  
  25.   public  
  26.     { Public 宣言 }  
  27.   end;  
  28.   
  29. var  
  30.   Form1: TForm1;  
  31.   
  32. implementation  
  33.   
  34. uses  
  35.   JclSchedule;  
  36.   
  37. {$R *.dfm}  
  38.   
  39. procedure TForm1.Button1Click(Sender: TObject);  
  40. var  
  41.   EventItem : TJvEventCollectionItem;  
  42.   IJclSched : JclSchedule.IJclSchedule;  
  43.   IDaySched : IJclDailySchedule;  
  44.   IDyaFreq : IJclScheduleDayFrequency;  
  45.   
  46. begin  
  47.   EventItem := FJvScheduledEvents.Events.Add;  
  48.   IJclSched := EventItem.Schedule;  
  49.   
  50.    //イベントアイテムのスケジュール自体は、  
  51.    //IJclScheduleで受けますが、実態はTJclScheduleで  
  52.    //IJclScheduleのほか  
  53.    //IJclScheduleDayFrequency,  
  54.    //IJclDailySchedule,  
  55.     //IJclWeeklySchedule,  
  56.    //IJclMonthlySchedule,  
  57.    //IJclYearlySchedule  
  58.    //を継承しています。  
  59.   
  60.    IJclSched.RecurringType := srkDaily;  
  61.   
  62.    IDaySched := (IJclSched as IJclDailySchedule);  
  63.    if Assigned(IDaySched) then  
  64.    begin  
  65.       //毎日実行する場合は、EveryWeekDayをFalseにして  
  66.       //間隔を1(日)にします。  
  67.       IDaySched.EveryWeekDay := false;  
  68.       IDaySched.Interval := 1;  
  69.    end;  
  70.   
  71.    IDyaFreq := (IJclSched as IJclScheduleDayFrequency);  
  72.    if Assigned(IDyaFreq) then  
  73.    begin  
  74.       IDyaFreq.StartTime := DateTimeToTimeStamp(Self.DateTimePicker1.Time).Time;  
  75.       IDyaFreq.EndTime   := IDyaFreq.StartTime;  
  76.       IDyaFreq.Interval := 1;  
  77.    end;  
  78.   
  79.    EventItem.Name := LabeledEdit1.Text;  
  80.    EventItem.OnExecute := JvScheduledEventsExecute;  
  81.    EventItem.Start;  
  82.   
  83. end;  
  84.   
  85. procedure TForm1.FormCreate(Sender: TObject);  
  86. begin  
  87.   FJvScheduledEvents := TJvScheduledEvents.Create(Self);  
  88. end;  
  89.   
  90. procedure TForm1.FormDestroy(Sender: TObject);  
  91. begin  
  92.   FJvScheduledEvents.Events.Clear;  
  93.   FJvScheduledEvents.Free;  
  94. end;  
  95.   
  96. procedure TForm1.JvScheduledEventsExecute(Sender: TJvEventCollectionItem;  
  97.   const IsSnoozeEvent: Boolean);  
  98. var  
  99.   JvCreateProcess: TJvCreateProcess;  
  100. begin  
  101.   
  102.   JvCreateProcess := TJvCreateProcess.Create(Self);  
  103.   try  
  104.     JvCreateProcess.CommandLine := Sender.Name;  
  105.     JvCreateProcess.WaitForTerminate := true;  
  106.     JvCreateProcess.Run;  
  107.   
  108.   finally  
  109.     JvCreateProcess.Free;  
  110.   end;  
  111.   
  112.   
  113. end;  
  114.   
  115. end.  

ポイントは、以下の2つかと思います。


  1. JclScheduleをUsesに加えることと
  2. TJvEventCollectionItem.Scheduleの戻り値がIJclSchedule型であるが実態はTJclSchedule型でIJclScheduleのほかIJclScheduleDayFrequency,IJclDailySchedule,IJclWeeklySchedule,IJclMonthlySchedule,
    IJclYearlyScheduleを継承していて設定したいスケジュールにあわせて適切にキャストする必要があること

今回のサンプルは、『ボタンを押したら指定した時刻にメモ帳を起動する』というタイマーで処理しても
十分なものですが、リフレクション、パッケージの動的ロードなどを使えば、もっと面白いことが
できそうな気がします。

0 件のコメント: