• ベストアンサー

ShellExecuteEx→WaitForSingleObjectで返ってこない

VC2008にて、エクスプローラもどきを作成しています。 ファイルアイコンをダブルクリックした時に、 関連付けされたアプリケーションで起動し、 そのファイルが閉じられたら、以降の処理を行うという 流れのプログラムを作成しています。 ファイル起動を、ShellExecuteで起動させ、 その後、WaitForSingleObjectを呼んで、 ファイルが閉じられるまで待つようにしています。 しかし、ファイルを閉じてもWaitFor~の次の処理に 来ず、困っています。 以下、ソースの抜粋になります。 ---------------ここから---------------- CString dir; dir = "C:\\test.doc"; SHELLEXECUTEINFO si; ZeroMemory( &si, sizeof(si) ); si.cbSize = sizeof(si); si.fMask = SEE_MASK_NOCLOSEPROCESS; si.lpVerb = _T("open"); si.lpFile = dir; si.nShow = SW_SHOWNORMAL; BOOL rtn; rtn = ShellExecuteEx( &si ); if ( rtn == 0 || (const int)si.hInstApp <= 32 ){ MessageBox( "open error" ); return; } WaitForSingleObject( si.hProcess, INFINITE ); CloseHandle( si.hProcess ); MessageBox( "次の処理start" ); ---------------ここまで---------------- ここでは、wordファイルをテストしているのですが、 ファイルを閉じても、完全にwordが終了せず、 2~3分後に、wordの方で、「予想以上に時間のかかる処理です。継続しますか?」との メッセージが表示されます。 「いいえ」を押すと、CloseHandleの行へ進むのですが、 「はい」を押すと、また2~3分後に同じメッセージが表示されます。 やりたい事は、wordに限らず、ファイルに関連付けされたアプリで 起動し、そのファイルが閉じられたら、次の処理に進むということです。 (本来は、これをマルチスレッドで実装予定です) 上記の処理で上手く返ってこないのは、どこか間違った箇所があるのでしょうか? ※ちなみに、WaitForSingleObjectで、INFINITEを指定せず、 WAIT_OBJECT_0が返ってくるまでwhileで回すなどの処理を試してみましたがダメでした。

質問者が選んだベストアンサー

  • ベストアンサー
  • ttega
  • ベストアンサー率52% (9/17)
回答No.1

SHELLEXECUTEINFO を MSDN で調べると書いてありますが、ShellExecuteEx は必ずしも hProcess にプロセスハンドルを入れてくれません。 普通は CreateProcess でプロセスを立ち上げて、そのハンドルで待機します。参考 URL などの例をご覧ください。

参考URL:
http://www.sm.rim.or.jp/~shishido/cprocess.html
lhouse
質問者

お礼

FindExecutable等の処理を省きたかったので CreateProcessを使わなかったのですが、 プロセスハンドルが入るとは限らないのであれば仕方ないですね。 大人しくCreateProcessでコーディングすることにします。

その他の回答 (1)

回答No.2

 こんばんは。  GUIの中でハマッているのでは無いでしょうか。  一応此れで応答しているのですが、駄目でしょうか。  http://msdn.microsoft.com/ja-jp/library/cc429261.aspx SHELLEXECUTEINFO si = {sizeof(si)}; si.fMask = SEE_MASK_NOCLOSEPROCESS; si.hwnd = hDlg; si.lpVerb = _T("open"); si.lpFile = _T("test.doc"); si.nShow = SW_SHOWNORMAL; BOOL rtn; rtn = ShellExecuteEx( &si ); if ( rtn == 0 || (const int)si.hInstApp <= 32 ){ MessageBox(NULL, "open error", "ok", IDOK); return FALSE; } BOOL fQuit = FALSE; MSG msg; while(fQuit == FALSE) { switch(MsgWaitForMultipleObjects(1, &si.hProcess, TRUE, 20, QS_ALLINPUT)) { case WAIT_OBJECT_0 : case WAIT_ABANDONED_0 : fQuit = TRUE; break; case WAIT_TIMEOUT : default : if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) == TRUE) { fQuit = (msg.message == WM_QUIT); TranslateMessage(&msg); DispatchMessage(&msg); } } } CloseHandle( si.hProcess ); MessageBox(NULL, "次の処理", "ok", IDOK); break;

lhouse
質問者

お礼

残念ながら、上記コーディングでも 上手くいきませんでした。 今回はCreateProcessでコーディングすることにしました。

関連するQ&A

専門家に質問してみよう