JCLのTJvCreateProcessを使ってバッチファイルの出力を取得する

JCLのTJvCreateProcessを使うと、バッチファイルを実行して、そのバッチファイルが出力した内容を取得することができます。

フォームにボタン(TButton)、リストボックス(TListBox)、TOpenDialog、TJvCreateProcessを配置します。

01

ボタンを押したときのイベントを記述します。

procedure TForm1.Button1Click(Sender: TObject);
begin
  if not OpenDialog1.Execute() then Exit;

  //実行するバッチファイルのファイル名
  JvCreateProcess1.CommandLine := OpenDialog1.FileName;

  //バッチファイルの出力をOnReadイベントで受け取る
  JvCreateProcess1.ConsoleOptions := JvCreateProcess1.ConsoleOptions + [coRedirect];

  //コンソール画面を表示しない
  JvCreateProcess1.StartupInfo.ShowWindow := swHide;
  JvCreateProcess1.StartupInfo.DefaultWindowState := False;

  //バッチファイルを実行する
  JvCreateProcess1.Run;
end;

これだけでバッチファイルを実行して、出力内容を取得できます。

バッチファイルの出力内容をリストボックスに表示します。

TJvCreateProcessのOnReadイベントを記述します。

procedure TForm1.JvCreateProcess1Read(Sender: TObject; const S: string;
  const StartsOnNewLine: Boolean);
begin
  if StartsOnNewLine then
    ListBox1.Items.Add(S)
  else
    ListBox1.Items[ListBox1.Count - 1] := S
end;

引数Sはコンソールから受け取ったデータです。
引数StartsOnNewLineは、受け取ったSが新しい行の始まりかどうかを示します。

TJvCreateProcessを使えば、これだけのコードで実現できました。

JCLのJclSysInfoで環境変数を取得する

JclSysInfoのGetEnvironmentVars関数を使うと、すべての環境変数を取得できます。

function GetEnvironmentVars(const Vars: TStrings): Boolean; overload;

引数に環境変数を格納するTStringsを渡します。
成功したときはTrue、失敗したときはFalseを返します。

uses JclSysInfo;

var
  S: TStringList;
begin
  S := TStringList.Create;
  GetEnvironmentVars(S);

JclSysInfoのGetEnvironmentVar関数を使うと、指定した変数名の値を取得できます。

function GetEnvironmentVar(const Name: string; out Value: string): Boolean; overload;

引数に変数名Nameと、値を格納するValueを渡します。
成功したときはTrue、失敗したときはFalseを返します。

uses JclSysInfo;

var
  CommandLine: string;
begin
  JclSysInfo.GetEnvironmentVar('COMSPEC', CommandLine);

XEAD ModelerをWindows8にインストールする

XEAD Modeler」は企業システムの基本設計情報を編集・閲覧するための専用ツールです。

010203

XEAD Modeler」の最新版はXEAD Modeler ダウンロードのページからダウンロードできます。

Windows8にインストールしようとしたところ、インストーラがWindows8に対応していないようでした。

04

INSTALL.EXEと同じフォルダーにあるINSTALL.DATをテキストエディタで編集して

[OSSetting]
CheckOSVersion=1

となっているところを、

[OSSetting]
CheckOSVersion=0

と変更すれば、インストールできました。

XEAD Modeler」はWindows8上で問題なく動作しています。

2013年2月20日追記
タイトルを修正しました。

トランザクションの処理を簡潔に書けるようにしてみた

データベースアプリケーションでは、エラーがなければコミット、エラーがあればロールバックという処理が頻繁に見られます。

たいていは次のようなコードになります。

var
  transaction: TDBXTransaction;
begin
  //トランザクションを開始する
  transaction := SQLConnection1.BeginTransaction;
  try
    //SQLを実行する
    SQLConnection1.Execute('insert into …');
    //トランザクションをコミットする
    SQLConnection1.CommitFreeAndNil(transaction);
  except
    //トランザクションをロールバックする
    SQLConnection1.RollbackFreeAndNil(transaction);
    raise;
  end;
end;

トランザクションを使用するときのコードは、SQLを実行する箇所以外は同じ処理になります。
そこで共通部分をまとめて、次のように記述できるようにします。

begin
  FTransactor.Perform(procedure
  begin
    SQLConnection1.Execute('insert into …');
  end);
end;

SQLを実行する部分のコードを無名関数で渡すことができるようにしました。
無名関数を渡せるようにすると、自由度が高くて使い勝手がよくなります。

FTransactorはTTransactor型のメンバ変数です。
TTransactor型は次のようになります。

type
  TTransactor = record
    FSQLConnection: TSQLConnection;
    constructor Create(SQLConnection: TSQLConnection);
    procedure Perform(Proc: TProc);
  end;

コンストラクタの引数でTSQLConnectionを渡します。

constructor TTransactor.Create(SQLConnection: TSQLConnection);
begin
  FSQLConnection := SQLConnection;
end;

フォームのコンストラクタでは、FTransactorを生成しています。

procedure TForm1.FormCreate(Sender: TObject);
begin
  FTransactor := TTransactor.Create(SQLConnection1);
end;

トランザクションのコミット・ロールバックを行うPerformメソッドは次のようになります。

procedure TTransactor.Perform(Proc: TProc);
var
  transaction: TDBXTransaction;
begin
  transaction := FSQLConnection.BeginTransaction;
  try
    Proc;
    FSQLConnection.CommitFreeAndNil(transaction);
  except
    FSQLConnection.RollbackFreeAndNil(transaction);
    raise;
  end;
end;

引数Procで無名関数を受け取っています。
無名関数は便利ですね。

このTTransactor型は『実践テスト駆動開発 テストに導かれてオブジェクト指向ソフトウェアを育てる』でJavaで書かれていたコードを参考にしました。