Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2005年02月15日] [更新 2013年10月22日] Delphi サンプルプログラム集
   
550_バッチファイルをフォームなしのアプリで実行
動作確認等 Windows 7 U64(SP1) + Delphi XE Pro
550_ConsoleBat3.zip [531 KB] 2013年10月22日版 (EXE 同梱)







バッチファイルをフォームなしのアプリで実行


フォームなしのアプリケーションからパッチファイルを実行します.
フォームなしのアプリでパッチファイルを実行するだけなら,パッチファイルをダブルクリックで起動するのと何ら変わりません.プログラムでパッチファイルを実行するということは,その他の処理も追加できるという利点があります.

本サンプルは CreateProcess 関数を使用して,コマンドプロンプトを非表示で起動しています.バッチファイルは実行時に作成して,実行後にこのバッチファイルを削除します.


[備考]
コマンドプロンプトに関しては以下の記事も参考にしてください.


図1
起動
  • 起動すると直ちにバッチファイル実行
  • コマンドプロンプトは非表示
  • [OK} をクリックすると,このアプリも終了
図2
出力ファイル
  • フォルダ内に TestDir.txt ができる
図3
TestDir.txt の例

リスト1
フォームを使用しないアプリで CreateProcess 関数を使用する例
program ConsoleBat3;

uses
  Windows, Classes, SysUtils, Forms;

{$R *.RES}

var
  BatFullPath : String;
  OutFullPath : String;
  SL          : TStringList;

//-----------------------------------------------------------------------------
//  CreateProcess関数を使用して,指定したファイルを実行する
//  起動したアプリが終了するまでこの関数が終了しないコードになっている
//-----------------------------------------------------------------------------
function WinExecAndWait32V2(FileName: string; Visibility: Integer): DWORD;
var
  StartupInfo : TStartupInfo;
  ProcessInfo : TProcessInformation;
begin
  Result := 0;

  FillChar(StartupInfo, SizeOf(StartupInfo), #0);
  StartupInfo.cb          := SizeOf(TStartupInfo);
  StartupInfo.dwFlags     := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := Visibility;

  SetLength(FileName, Length(FileName));

  //参照カウンタ対策
  UniqueString(FileName);
  if not CreateProcess(nil,
                       PChar(FileName),
                       nil,
                       nil,
                       False,
                       CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
                       nil,
                       nil,
                       StartupInfo,
                       ProcessInfo) then begin
    Result := WAIT_FAILED;
  end else begin
    //起動したプロセスが終了するまで待つ
    while WaitForSingleObject(ProcessInfo.hProcess, 100) = WAIT_TIMEOUT do
      Application.ProcessMessages;

    GetExitCodeProcess(ProcessInfo.hProcess, Result);
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
  end;
end;

//=============================================================================
//  バッチファイルの実行例
//  指定ディレクトリリストを,このフォルダにTestDir.txtで保存
//
//  BatFullPath バッチファイルの保存先
//  OutFullPath 出力先のファイルの保存先
//  終了後にDEL %0で作成したバッチファイル自身を削除する
//=============================================================================
begin
  SL := TStringList.Create;

  BatFullPath := ExtractFilePath(Application.ExeName) + 'Testbat.BAT';
  OutFullPath := ExtractFilePath(Application.ExeName) + 'TestDir.TXT';

  DeleteFile(OutFullPath);
  //バッチファイルを作成してこのアプリのフォルダに保存
  try
    SL.Add('CD D:\');
    SL.Add('DIR>' + OutFullPath);
    SL.Add('DEL %0');
    SL.Add('EXIT');
    SL.SaveToFile(BatFullPath);
  finally
    SL.Free;
  end;
  //バッチの実行
  WinExecAndWait32V2(BatFullPath, SW_HIDE);

  //ここでも削除可能
  //DeleteFile(BatFullPath);
  MessageBox(0, '終了しました', 'バッチ処理', MB_ICONINFORMATION);
end.