Word文書を広げて、閉じるまで待機したいです。
CreateProcess で Word文書を指定して起動する場合、Wordのパスが必要になります(関連付けされていたら)
このWordのパスを拾ってくるには、どうしたらいいでしょう?
例えばうちの環境であれば、レジストリから以下のように拾うことができます。
HKEY_CLASSES_ROOT\.doc を読んで「Word.Document.8」を取得
HKEY_CLASSES_ROOT\Word.Document.8\shell\open\command を見てパスを取得
拡張子とかファイルのパスから、関連づけされたプログラムを取得する関数なんかは、ないもんでしょういか?
開発環境 Windows XP + Delphi 5
単に「閉じるまで待機」したいだけですよね?
それなら関連づけされたプログラムを探すんじゃなくて Application.ProcessMessages で待てば良いと思います。もちろん文書自体は関連付けで開きます。以下は大昔に書いたプログラムの一部です。このまま動くわけではありませんが、ご参考になさって下さい。
(* プログラム起動と終了待ち *)
procedure ProgramStart(PRGLine, CMDLine, DIR, CNF : String);
var
SI : TStartupInfo;
PI : TProcessInformation;
begin
FillChar(SI, SizeOf(TStartUpInfo), 0);
if UpperCase(copy(PRGLine,(length(PRGLine) - 3), 4)) = '.BAT' then begin
SI.wShowWindow := SW_MINIMIZE;
SI.dwFlags := STARTF_USESHOWWINDOW;
end;
if CMDLine <> '' then PRGLine := PRGLine + ' ' + CMDLine;
if DIR <> '' then {$I-} ChDir(DIR); {$I+}
if IOResult <> 0 then
ShowBeepMes('指定された作業フォルダ(' + DIR + ') に 移動できません!')
else begin
if CNF = '' then
WinExec(PChar(PRGLine), SW_SHOWNORMAL)
else begin
if CreateProcess(NIL, PChar(PRGLine), NIL, NIL, FALSE,
CREATE_DEFAULT_ERROR_MODE, NIL, NIL, SI, PI) then begin
while WaitForSingleObject(PI.hProcess, 0) = WAIT_TIMEOUT do begin
Application.ProcessMessages;
end;
ShowBeepMes(CNF);
end
else begin
ShowBeepMes('プログラムが起動出来ませんでした');
end;
end;
end;
end;
> Word文書を広げて、閉じるまで待機したいです。
という目的だけならShellExecuteExでSEE_MASK_NOCLOSEPROCESSを指定すればできますが、
どうしてもプログラム名が知りたいならFindExecutableで。
う〜むさん>
説明不足でした。
CreateProcessでは、ワード文書名を指定するだけでは開くことができませんでした。
ですが、「プログラム名 + 文書名」を与えると開くことができたので、
プログラム名があれば、いいのでは?と思い質問しました。
tttさん>
ありがとうございました。
FindExecutableで、プログラム名のパスを取ってくることができることを確認し、
また、ShellExecuteExでSEE_MASK_NOCLOSEPROCESSを指定することで、終了待ちできることも確認しました。
なお、FindExecutableは、今回知識に留めておき、ShellExecuteExで実装するようにしました。
だいたいこんな感じです
var
info: TShellExecuteInfo;
begin
FillChar(info, SizeOf(TShellExecuteInfo), 0);
info.cbSize := SizeOf(TShellExecuteInfo);
info.fMask := SEE_MASK_NOCLOSEPROCESS;
info.Wnd := Application.Handle;
info.lpVerb := 'open';
info.lpFile := てきとうなWord文書;
info.nShow := SW_SHOW;
if ShellExecuteEx(@info) and i(nfo.hInstApp >= 32) then begin
while WaitForSingleObject(info.hProcess, 100) = WAIT_TIMEOUT do begin
Application.ProcessMessages;
end;
CloseHandle(info.hProcess);
end;
end;
間違い発見
× if ShellExecuteEx(@info) and i(nfo.hInstApp >= 32) then begin
○ if ShellExecuteEx(@info) and (info.hInstApp >= 32) then begin
ツイート | ![]() |