5

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

hProcess = 152

次に、このプロセスハンドルを名前付きパイプを介して最初のプロセスに渡します。最初のプロセス(イベントハンドルが有効な場合)では、重複ハンドルを呼び出します。

DuplicateHandle( hFirstProcess, hEvent, hSecondProc, hDupEvent, DUPLICATE_SAME_ACCESS, 0, 0)

残念ながら、エラーが発生します。

DuplicateHandle hPipeFCGI GetLastError=6-ハンドルが無効です。

さらにテスト(hFirstProcessを置き換える)すると、無効なのはhSecondProcであることがわかります!??

ビッグミステリー。

4

4 に答える 4

2

IPCには名前付きパイプまたはメールスロットを使用します。これは、目的に応じて確実に機能するはずです。待機する必要がある場合は、名前付き待機ハンドルを使用してください。

それ以外の場合は、ハンドルの所有権を正しく設定するために、2番目のプロセスでDuplicateHandleを実行することを選択します。

于 2009-05-04T11:36:30.210 に答える
2

プロセスハンドルはプロセスIDとは異なります。OpenProcessはプロセスIDを取ります。次のようなものを使用してください...

HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE、FALSE、GetCurrentProcessId());

于 2012-08-17T06:42:31.827 に答える
1

私が正しく理解していれば、同じイベントを通じて2つの無関係なプロセスを同期させたいと思います。その場合は、名前付きイベントを使用できます。

CreateEvent API関数を使用して作成し、名前を付けてから、2番目のプロセスからOpenEvent API関数を使用して、イベントの名前を指定します。

ミューテックス( OpenMutex)やセマフォ(OpenSemaphore )など、他の同期オブジェクトにも同様の機能があります。

于 2009-05-04T11:36:20.897 に答える
1
  1. どういうわけか、2番目のプロセスは最初のプロセスにそのプロセスIDを取得する必要があります。これは、GetCurrentProcessId()
  2. 最初のプロセスは、このIDを使用HANDLEして2番目のプロセスに移動する必要があります。hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId);
  3. これで、2番目のプロセスのREALプロセスハンドルと最初のプロセスの疑似ハンドルを使用して、最初のプロセスでハンドルを複製できます。DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &hDupEvent, 0, FALSE, DUPLICATE_SAME_ACCESS);
  4. 最終的に作成したハンドルを解放することを忘れないでくださいOpenProcess(それがどのような違いをもたらすかはわかりませんが、あなたはそうすることになっています...)。また、イベントへの両方のハンドルを解放します。2番目のプロセスに与えられたハンドルと最初のハンドルです。
于 2011-11-05T00:12:40.847 に答える