DuplicateHandle()、最初のプロセスで使用しますか、それとも 2 番目のプロセスで使用しますか?
質問
Windows API DuplicateHandle()http://msdn.microsoft.com/en-us/library/ms724251(VS.85).aspxオブジェクト ハンドルを複製し、元のプロセスと複製されたハンドルを使用する他のプロセスの両方へのハンドルが必要です。
2 つの UNRELATED プロセスがある場合、必要なハンドルが利用可能である限り、どちらのプロセスでも DuplicateHandle() を呼び出すことができると想定しています。
私の質問は、パイプを使用して 2 つのプロセス間で通信し、イベントでこれを実現することについてです。
最初のプロセスでは CreateEvent() を実行します。次に、2番目のプロセスでWaitForSingleObject()を使用したいと思います。
最初のプロセスでハンドルを複製しようとすると、最初にパイプ経由で 2 番目のプロセスのハンドルを最初のプロセスに送信し、ハンドルを複製してから、そのハンドルを 2 番目のプロセスに送信する必要がありますか?
あるいは、最初のプロセス ハンドルとイベント ハンドルを 2 番目のプロセスに送信することから始めて、そこで複製することもできます。
どちらかを選択しなければならない理由はありますか?
しわを加えるために、イベント ハンドルは実際には最初のプロセス (CGI アプリケーション) を実際に呼び出した親プロセスから継承されます。そのイベント ハンドルが HANDLE_DO_NOT_DUPLICATE (そのようなもの) で作成された場合、実際に DuplicateHandle() を使用して 2 番目のプロセス用にそれを複製できますか?
応答:
提案されているように、最初のプロセスで新しい NAMED イベントを作成し、2 番目のプロセスでそれを見つけることはできますが、最初のプロセスの親で作成されたイベントを複製して 2 番目のプロセスに転送しようとしています。このイベントは名前付きイベントではないため、DuplicateHandle() を使用する必要があります。
IPCにはパイプを使用しています。イベントハンドルが2番目のプロセスに送信されるときにコンテキスト外になるため、DuplicateHandle()を最初のプロセスで呼び出す必要があることに気づきました。
hProcPseudo = GetCurrentProcess()
//Then call either:
lpRealHandle = OpenProcess( PROCESS_DUP_HANDLE, 0, hProcPseudo )
//This fails with GetLastError= 87 - The parameter is incorrect ???
// same thing with PROCESS_ALL_ACCESS ??
//OR
lRet = DuplicateHandle( hProcPseudo, hProcPseudo, hProcPseudo, lpRealHandle, DUPLICATE_SAME_ACCESS, 0, 0 )
//then I can Duplicate my Event Handle in the first thread with:
lRet = DuplicateHandle( hLocalProcess, hEvent, lpRealHandle, hDupEvent, DUPLICATE_SAME_ACCESS, 0, 0)
2 番目のプロセスは、上記の変換で説明した DuplicateHandle() を使用してハンドルを変換します。
hProcPseudo= 4294967295
に
hプロセス= 152
次に、このプロセス ハンドルを名前付きパイプ経由で最初のプロセスに渡します。最初のプロセス (イベント ハンドルが有効な場合) では、Duplicate handle を呼び出します。
DuplicateHandle( hFirstProcess, hEvent, hSecondProc, hDupEvent, DUPLICATE_SAME_ACCESS, 0, 0)
残念ながら、次のエラーが発生します。
DuplicateHandle hPipeFCGI GetLastError= 6 - ハンドルが無効です。
さらにテストを行ったところ (hFirstProcess を置き換え)、無効なのは hSecondProc であることが判明しました。
ビッグミステリー。
他のヒント
プロセスハンドルはプロセスIDとは異なります。 OpenProcessはプロセスIDを受け取ります。次のようなものを使用してください...
ハンドルhProcess = OpenProcess(PROCESS_DUP_HANDLE、FALSE、GetCurrentProcessId());
正しく理解できた場合、同じイベントを介して2つの無関係なプロセスを同期する必要があります。その場合、名前付きイベントを使用できます。
CreateEvent API関数を使用して作成する、名前を指定し、2番目のプロセスから OpenEventを使用します API関数。イベントの名前を指定します。
ミューテックス( OpenMutex )またはセマフォ( OpenSemaphore ) 。
- どういうわけか、2番目のプロセスはそのプロセスIDを最初のプロセスに取得する必要があります。これは、
GetCurrentProcessId()
- 最初のプロセスは、このIDを使用して2番目のプロセスへの
HANDLE
を取得する必要があります:hProcess = OpenProcess(PROCESS_DUP_HANDLE、FALSE、dwProcessId);
- 2番目のプロセスのREALプロセスハンドルと最初のプロセスの擬似ハンドルを使用して、最初のプロセスのハンドルを複製できるようになりました:
DuplicateHandle(GetCurrentProcess()、hEvent、hProcess、& hDupEvent、 0、FALSE、DUPLICATE_SAME_ACCESS);
- 最終的に
OpenProcess
で作成したハンドルをリリースすることを忘れないでください(どのような違いが生じるかわかりませんが、あなたは...)。また、イベントの両方のハンドル(2番目のプロセスに与えられたものと最初のハンドル)を解放します。