5

Windows API DuplicateHandle() http://msdn.microsoft.com/en-us/library/ms724251(VS.85).aspx 需要复制对象句柄以及原始进程和另一个进程的句柄你想使用重复的句柄。

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

我的问题是关于使用管道在两个进程之间进行通信以通过事件实现这一点。

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

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

或者,我可以首先将第一个进程句柄和事件句柄发送到第二个进程,然后在那里复制它。

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

要添加一个皱纹,事件句柄实际上是从实际调用第一个进程(这是一个 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

h进程= 152

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

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

不幸的是,我得到了错误:

DuplicateHandle hPipeFCGI GetLastError= 6 - 句柄无效。

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

大奥秘。

4

4 回答 4

2

为 IPC使用命名管道邮槽,这应该可以可靠地满足您的目的。如果您需要等待,请使用命名的等待句柄。

否则,我会选择在第二个过程中执行 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

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

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

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

于 2009-05-04T11:36:20.897 回答
1
  1. 不知何故,第二个进程需要将其进程 ID 传递给第一个进程。这可以通过GetCurrentProcessId()
  2. 第一个进程现在需要使用这个 ID 来获取HANDLE第二个进程:hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId);
  3. 现在您可以复制第一个进程中的句柄,使用第二个进程的 REAL 进程句柄和第一个进程的伪句柄:DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &hDupEvent, 0, FALSE, DUPLICATE_SAME_ACCESS);
  4. 请记住最终释放您创建的句柄OpenProcess(我不知道它会产生什么不同,但您应该......)。此外,释放事件的两个句柄:赋予第二个进程的句柄和初始句柄。
于 2011-11-05T00:12:40.847 回答