DuplicateHandle(),在第一个或第二个过程中使用?

时间:2009-05-04 11:24:59

标签: c++ winapi ipc

Windows API DuplicateHandle() http://msdn.microsoft.com/en-us/library/ms724251(VS.85).aspx 需要复制Object句柄以及原始进程和要使用重复句柄的其他进程的句柄。

我假设如果我有两个UNRELATED进程,只要我有所需的句柄,我可以在任何一个中调用DuplicateHandle()吗?

我的问题是关于使用Pipe在两个进程之间进行通信以实现此事件。

在第一个过程中我创建了CreateEvent()。现在我想在第二个进程中使用WaitForSingleObject()。

如果我尝试在第一个进程中复制句柄,我需要先通过管道将第二个进程句柄发送到第一个进程,复制句柄然后将句柄发送到第二个进程?

另外,我可以先将第一个进程句柄和Event句柄发送到第二个进程,然后在那里复制它。

我有理由选择其中一个吗?

要添加皱纹,事件句柄实际上是从实际调用第一个进程(即CGI应用程序)的父进程继承的。如果使用HANDLE_DO_NOT_DUPLICATE(类似的东西)创建了该事件句柄,那么我实际上可以使用DuplicateHandle()来复制第二个进程吗?

响应:

好吧,我可以在第一个进程中创建一个新的NAMED事件,并按照建议在第二个进程中找到它,但我试图重复在第一个进程的父进程中创建的事件并将其转发到第二个进程。此事件不是命名事件,因此我需要使用DuplicateHandle()。

我正在使用IPC管道。我意识到必须在第一个进程中调用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)

第二个进程使用上面详述的DuplicateHandle()转换其句柄

hProcPseudo = 4294967295

hProcess = 152

然后我通过命名管道将此进程句柄传递给第一个进程。 在第一个进程中(事件句柄有效)我调用Duplicate handle:

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

不幸的是我收到了错误:

DuplicateHandle hPipeFCGI GetLastError = 6 - 句柄无效。

进一步测试(代替hFirstProcess)显示它是无效的hSecondProc!??

大谜。

4 个答案:

答案 0 :(得分:2)

对IPC使用named pipemailslots,这应该可靠地用于您的目的。如果您需要等待,请使用命名等待句柄。

否则,我会选择在第二个过程中执行DuplicateHandle,以便正确设置句柄所有权。

答案 1 :(得分:2)

流程句柄与流程ID不同。 OpenProcess采用进程ID。使用像...这样的东西。

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

答案 2 :(得分:1)

如果我理解正确,您希望通过同一事件同步两个不相关的进程。如果是这样,您可以使用命名事件。

使用CreateEvent API函数创建一个,为其提供一个名称,然后从第二个流程使用OpenEvent API函数,指定事件的名称。

您有其他同步对象的类似功能,例如互斥锁(OpenMutex)或信号量(OpenSemaphore)。

答案 3 :(得分:1)

  1. 不知何故,第二个进程需要将其进程ID提供给第一个进程。这可以通过GetCurrentProcessId()
  2. 获得
  3. 现在,第一个流程需要使用此ID来获取第二个流程的HANDLEhProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId);
  4. 现在,您可以使用第二个流程的REAL流程句柄和第一个流程的伪句柄复制第一个流程中的句柄:DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &hDupEvent, 0, FALSE, DUPLICATE_SAME_ACCESS);
  5. 记得最终释放你用OpenProcess创建的句柄(我不知道它会有什么不同,但你应该......)。另外,释放BOTH处理事件的句柄:给第二个进程和初始句柄的句柄。