2010年11月2日火曜日

JvScheduledEventsを試してみる。

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

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

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

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

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, JvScheduledEvents, StdCtrls, ExtCtrls, ComCtrls, JvComponentBase,
  JvCreateProcess;

type
  TForm1 = class(TForm)
    Button1: TButton;
    DateTimePicker1: TDateTimePicker;
    Label1: TLabel;
    LabeledEdit1: TLabeledEdit;

    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    FJvScheduledEvents : TJvScheduledEvents;
    procedure JvScheduledEventsExecute(Sender: TJvEventCollectionItem;
              const IsSnoozeEvent: Boolean);
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  JclSchedule;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  EventItem : TJvEventCollectionItem;
  IJclSched : JclSchedule.IJclSchedule;
  IDaySched : IJclDailySchedule;
  IDyaFreq : IJclScheduleDayFrequency;

begin
  EventItem := FJvScheduledEvents.Events.Add;
  IJclSched := EventItem.Schedule;

   //イベントアイテムのスケジュール自体は、
   //IJclScheduleで受けますが、実態はTJclScheduleで
   //IJclScheduleのほか
   //IJclScheduleDayFrequency,
   //IJclDailySchedule,
    //IJclWeeklySchedule,
   //IJclMonthlySchedule,
   //IJclYearlySchedule
   //を継承しています。

   IJclSched.RecurringType := srkDaily;

   IDaySched := (IJclSched as IJclDailySchedule);
   if Assigned(IDaySched) then
   begin
      //毎日実行する場合は、EveryWeekDayをFalseにして
      //間隔を1(日)にします。
      IDaySched.EveryWeekDay := false;
      IDaySched.Interval := 1;
   end;

   IDyaFreq := (IJclSched as IJclScheduleDayFrequency);
   if Assigned(IDyaFreq) then
   begin
      IDyaFreq.StartTime := DateTimeToTimeStamp(Self.DateTimePicker1.Time).Time;
      IDyaFreq.EndTime   := IDyaFreq.StartTime;
      IDyaFreq.Interval := 1;
   end;

   EventItem.Name := LabeledEdit1.Text;
   EventItem.OnExecute := JvScheduledEventsExecute;
   EventItem.Start;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FJvScheduledEvents := TJvScheduledEvents.Create(Self);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FJvScheduledEvents.Events.Clear;
  FJvScheduledEvents.Free;
end;

procedure TForm1.JvScheduledEventsExecute(Sender: TJvEventCollectionItem;
  const IsSnoozeEvent: Boolean);
var
  JvCreateProcess: TJvCreateProcess;
begin

  JvCreateProcess := TJvCreateProcess.Create(Self);
  try
    JvCreateProcess.CommandLine := Sender.Name;
    JvCreateProcess.WaitForTerminate := true;
    JvCreateProcess.Run;

  finally
    JvCreateProcess.Free;
  end;


end;

end.


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


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

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

0 件のコメント: