関連付けされたプログラムが欲しい

解決


トリッキー  2009-01-22 03:08:15  No: 33187

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


う〜む  2009-01-22 03:57:30  No: 33188

単に「閉じるまで待機」したいだけですよね?

それなら関連づけされたプログラムを探すんじゃなくて  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;


ttt  2009-01-22 03:58:33  No: 33189

> Word文書を広げて、閉じるまで待機したいです。
という目的だけならShellExecuteExでSEE_MASK_NOCLOSEPROCESSを指定すればできますが、
どうしてもプログラム名が知りたいならFindExecutableで。


トリッキー  2009-01-22 18:12:03  No: 33190

う〜むさん>
説明不足でした。
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;


トリッキー  2009-01-22 18:14:38  No: 33191

間違い発見

×  if ShellExecuteEx(@info) and i(nfo.hInstApp >= 32) then begin
○  if ShellExecuteEx(@info) and (info.hInstApp >= 32) then begin


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加