Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2005年02月01日] [更新 2013年10月21日] Delphi サンプルプログラム集
430_自分で起動したアプリの終了を待つ ( エクセルの場合 )
動作確認等 Windows 7 U64(SP1) + Delphi XE Pro
430_ExcelCreateProcess.zip [541 KB] 2013年10月21日版 (EXE 同梱)



  • 2012年04月10日
  • Excel 2007 用にコード修正
  • Windows 7 U64(SP1) + Delphi XE Proで動作確認




自分で起動したアプリの終了を待つ ( エクセルの場合 )


これもネット上に多くのサイトにあります.ここではエクセル関係のページが続いたので,ついでにエクセルの場合の例とします.起動時にブックを指定する場合は,ショートカットのリンク先のように,起動アプリ名の後にブック名を付け足します.

コード中のエクセルのパス名は筆者の環境のものです.各自のパスに修正してください.


図1
実行開始画面
図2
表示位置は画面右上隅
図3
エクセルを起動
  • エクセルを閉じないと終了できない

リスト1
CreateProcess 関数でエクセルを起動し,エクセルが終了するまで待つ
unit Excel_CreateProcessUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, ComObj;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure FormShow(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//-----------------------------------------------------------------------------
//  CreateProcess関数を使用して,指定したファイルを実行する
//  起動したアプリが終了するまでこの関数が終了しないコードになっている
//-----------------------------------------------------------------------------
function WinExecAndWait32(FileName: string; Visibility: Integer): Longword;
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;

//=============================================================================
//  エクセルに隠れないように画面右上に表示
//  FormのFormStyleはfsStayOnTopにしている
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
  Self.Left := Screen.Width - Self.Width;
  Self.Top  :=0;
end;

//=============================================================================
//  エクセルを起動して終了を待つ
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);

  //---------------------------------------------------------------------------
  //  環境変数文字列から実際のフルパスを取得する関数
  //---------------------------------------------------------------------------
  function ExpandEnvironmentString(S: String): String;
  var
    DstChar : array [0..MAX_PATH-1] of Char;
  begin
    ExpandEnvironmentStrings(PChar(S), DstChar, MAX_PATH);
    Result := DstChar;
  end;
  //---------------------------------------------------------------------------

var
  AppStr : String;
begin
  Self.Enabled := False;

  //エクセルのフルパスを指定する
  AppStr := '%ProgramFiles%\Microsoft Office\Office12\EXCEL.EXE';
  AppStr := ExpandEnvironmentString(AppStr);

  if WinExecAndWait32(PChar(AppStr), SW_SHOWNORMAL) = WAIT_FAILED then begin
    Application.MessageBox('エクセルを起動できませんでした', '結果');
  end else begin
    Application.MessageBox('エクセルが終了しました', '結果');
  end;

  Self.Enabled := True;
end;

//=============================================================================
//  閉じる
//  エクセル起動中は閉じることはできない
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  Close;
end;

end.