おせわになります。
下記のコードでは、メイン処理をスレッド化し、
そのスレッドの中でさらに、別スレッド(孫スレッド)を作成していますが、
そこで、ShellExecuteEx関数にてEXEファイルを実行しています。
EXEファイルは、計算処理プログラムのため、計算処理終了まで、
WaitForSingleObject関数で計算処理終了を待っています。
しかし、WaitForSingleObject関数がうまく動作せずに、
計算処理終了を待たずに次の処理へ移ってしまい、原因がわからなくて
困っています。
※但しデバッグコンパイル後の実行はうまく動作する。
どなたかご教授ねがいます。
//メイン処理
main
{
m_pThread = AfxBeginThread( ThreadFunc , this ); //スレッド起動
WaitForSingleObject( m_pThread->m_hThread, INFINITE);
//スレッド終了を待つ
}
//スレッド処理
static UINT ThreadFunc( LPVOID pParam );
{
メイン処理...
m_pThread_Sub = AfxBeginThread( ThreadFunc_Sub , this );
//サブスレッド起動
}
//孫スレッド処理
static UINT ThreadFunc_Sub( LPVOID pParam );
{
SHELLEXECUTEINFO flowx={sizeof(test),SEE_MASK_NOCLOSEPROCESS,
NULL,"open","d:\test.exe",NULL,NULL,SW_HIDE,
AfxGetApp()->m_hInstance};
ShellExecuteEx(&test); //起動
WaitForSingleObject(flowx.hProcess,INFINITE);
//ここでtest.exeの終了を待ってくれない
}
こんにちわ。
>計算処理終了を待たずに次の処理へ移ってしまい、
「次の処理」ってどこの事でしょうか?
子スレッドは孫スレッドの終了を待っていないので、子スレッドは即終了し、メインスレッドのWaitForSingleObject()も即脱出すると思いますよ。
ありがとうございます。
>「次の処理」ってどこの事でしょうか?
>子スレッドは孫スレッドの終了を待っていないので、
>子スレッドは即終了し、メインスレッドのWaitForSingleObject()も
>即脱出すると思いますよ。
大変失礼しました。コードの転記を間違えました。
//メイン処理
main
{
m_pThread = AfxBeginThread( ThreadFunc , this ); //子スレッド起動
}
//子スレッド処理
static UINT ThreadFunc( LPVOID pParam );
{
メイン処理...
m_pThread_Sub = AfxBeginThread( ThreadFunc_Sub , this );
//孫スレッド起動
WaitForSingleObject( m_pThread->m_hThread, INFINITE);
//子スレッドが孫スレッド終了を待つ
メイン処理続く...
}
//孫スレッド処理
static UINT ThreadFunc_Sub( LPVOID pParam );
{
SHELLEXECUTEINFO flowx={sizeof(test),SEE_MASK_NOCLOSEPROCESS,
NULL,"open","d:\test.exe",NULL,NULL,SW_HIDE,
AfxGetApp()->m_hInstance};
ShellExecuteEx(&test); //起動
WaitForSingleObject(flowx.hProcess,INFINITE);
//ここでtest.exeの終了を待ってくれない
}
孫スレッドでは、ShellExecuteEx()関数を実行しているのですが、
別の処理(1分程度のループ処理)に変えてみたら
WaitForSingleObject()関数が正常に動いているようでした。
どうもShellExecuteEx()関数の実行方法に問題があるようなのですが
原因がわからなくて困っていますので教えていただけたらと思います。
なお、デバッグコンパイルではうまく動作するのですが...
> SHELLEXECUTEINFO flowx={sizeof(test),SEE_MASK_NOCLOSEPROCESS,
> NULL,"open","d:\test.exe",NULL,NULL,SW_HIDE,
> AfxGetApp()->m_hInstance};
・test って何ですか?
・ファイル名は "d:\\test.exe" ではないですか?
・hInstApp は結果が返されるものであり、値を与える必要ははありません
回答ありがとうございます。
お騒がせしましたが、私のうっかりミスでした。
ShellExecuteExで起動している"test.exe"は、デバッグコンパイルと
リリースコンパイルとで、各々のフォルダ(デバッグであれば"Debug"フォルダ)
の下位フォルダに保存されているものを使用していますが、"Release"フォルダ
の下位フォルダに保存していた"test.exe"は、不具合が含まれたものになって
いました。
ShellExecuteEx()は、スレッドの中からはうまく呼び出せないのかと
おもっていましたが、そういう問題はないようですね。
ただ、「シェル呼び出し関数とマルチスレッド アパートメントからの
インターフェイス」についての下記URLにて
"関数がマルチスレッド区画として初期化されるスレッドからアクセスしようとき、
完全に失敗することがあります。"
と記載されているので、ちょっと気になるところではあります。
(記載されている内容が、私の知識不足か、理解に苦しみますが...)
http://support.microsoft.com/default.aspx?scid=kb;ja;287087
>test って何ですか?
失礼しました。
SHELLEXECUTEINFO test = {sizeof(test),...}
でした。
>ファイル名は "d:\\test.exe" ではないですか?
その通りです。エスケープ文字必要ですよね。
>hInstApp は結果が返されるものであり、値を与える必要ははありません
SHELLEXECUTEINFOのヘルプが英語であること、また、ネット上で調べても
なかなか出てこないため、全てを把握できていませんでした。
これでも正常に動作しているようですが、必要がなければ引数なしに変更します。
ツイート | ![]() |