获取在外部进程中打开的命名管道的HANDLE(win32)

时间:2013-03-20 15:17:34

标签: winapi named-pipes handle

我有一个日志记录工具(SS_Log的后代),它由一个独立的日志查看器和一个C ++ lib组成,用于通过命名管道发送消息。

当记录第一条消息时,客户端通过C ++ lib启动日志查看器,并且

HANDLE hPipe = CreateNamedPipe( szPipeName,
                                PIPE_ACCESS_DUPLEX, 
                                PIPE_TYPE_MESSAGE|PIPE_WAIT|PIPE_READMODE_MESSAGE, 
                                PIPE_UNLIMITED_INSTANCES, 
                                SSLOG_MAX_MESSAGE_LENGTH,
                                0, 5000, &sa );

pView->Pipe(hPipe);

if( pView->Pipe() == INVALID_HANDLE_VALUE )
{
    pView->MessageBox( _T("Could not create the pipe for incoming messages.  No messages can be received.   "), 
        _T("Fatal Error"), MB_OK|MB_ICONSTOP );
    return FALSE;
}

// now we loop forever, waiting for messages.  As they come in, send them
// to the SS_Log_WindowView::EraseLog() and SS_Log_WindowView::WriteLog()
// functions as appropriate.
while( TRUE )
{
    ConnectNamedPipe( pView->Pipe(), NULL );
    ...
}

当客户想要发送消息时,它会

BOOL bResult = WaitNamedPipe(WindowPipeName(), 20000);
            bResult = CallNamedPipe(WindowPipeName(), (LPVOID)szFinalBuffer, 
                             _tcslen(szFinalBuffer)+1, (LPVOID)NULL, 
                             0, &dwBytesRead, 
                             5000);

我想获得一个与这个命名管道相对应的HANDLE。文档建议我可以使用CreateFile( WindowPipeName(), GENERIC_READ|GENERIC_WRITE,...OPEN_EXISTING,...)创建一个。当我这样做时,一些东西显然开始阻塞,日志查看器不再收到任何消息。甚至没有用那个HANDLE做任何事情。

是否有可能做我想要的,如果可以,怎么做?

1 个答案:

答案 0 :(得分:1)

日志查看器的循环以调用ConnectNamedPipe开始。所以它等待客户端连接,读取消息,返回到循环的顶部并等待客户端再次连接。

这适用于CallNamedPipe,因为该函数每次发送消息时都会连接和断开连接。

但是如果客户端通过使用CreateFile打开管道句柄来创建持久连接,那么它只连接一次。在服务器中,对ConnectNamedPipe的第二次调用将挂起,等待另一个客户端连接。

如果您希望日志查看器仅处理具有持久连接的单个客户端,则可以使用一个循环来调用ConnectNamedPipe,然后使用内部循环来处理来自客户端的消息,直到管道关闭为止。

如果您想处理多个客户端,那么您当前的解决方案比尝试处理多个同时连接要简单得多。