WriteFile函数“冻结”

时间:2009-11-19 23:58:13

标签: c++ windows

我正在尝试重写xCmd,它可以在远程计算机上启动进程。基本上,它将自身安装为目标计算机上的服务,然后启动所请求的进程。一切都很好,但我注意到一个错误。 xCmd通过管道进行通信,它使用WriteFile()。我的问题是,如果我运行我的API(或最初,都产生此错误),那么它将首次启动请求的进程,但如果我再次启动它,那么它将“冻结”在这一行:

WriteFile( hCommandPipe, &msg, sizeof(msg), &dwTemp, NULL );

WriteFile没有返回任何错误代码,程序就在这里停止。我甚至无法关闭cmd窗口。当我关闭目标计算机上的服务时,我只能关闭它。 任何人都可以帮我解决这个问题吗?这真烦人,我不知道:(

以下是无法正常工作的功能:

 BOOL ExecuteRemoteCommand()
 {
 DWORD dwTemp = 0;
 xCmdMessage msg;
 xCmdResponse response;

 ::ZeroMemory( &msg, sizeof(msg) );
 ::ZeroMemory( &response, sizeof(response) );

 FillMessage( &msg );

 // Send message to service
 WriteFile( hCommandPipe, &msg, sizeof(msg), &dwTemp, NULL );

 // Connects to remote pipes (stdout, stdin, stderr)
 if ( ConnectToRemotePipes( 5, 1000 ) )
 {
   StdOutput( _T("Ok\n\n") );

    // Waiting for response from service
    ReadFile( hCommandPipe, &response, sizeof(response), &dwTemp, NULL );
 }
 else
    StdOutput( _T("Failed\n\n") );

 if ( response.dwErrorCode == 0 ) 
    _tprintf( _T("\nRemote command returned %d(0x%X)\n"), 
              response.dwReturnCode, 
              response.dwReturnCode );
 else
    _tprintf( _T("\nRemote command failed to start. Returned error code is %d(0x%X)\n"), 
              response.dwErrorCode, 
              response.dwErrorCode );

 return TRUE;
}

提前致谢!

kampi

2 个答案:

答案 0 :(得分:5)

我认为这意味着管道连接的另一端不是从管道中读取数据而管道缓冲区已满。

它也可能表示另一端已关闭其管柄。对于在尝试编写时会导致错误的匿名管道,但我不记得命名管道是否也是如此。

  

如果应用程序使用WriteFile函数写入管道时管道缓冲区已满,则写入操作可能无法立即完成。当读取操作(使用ReadFile函数)为管道提供更多系统缓冲区空间时,将完成写入操作。

     

MSDN

     

写操作将阻塞,直到从管道读取数据,以便释放额外的缓冲区配额。

     

MSDN

答案 1 :(得分:1)

在多线程管道服务器中,管道客户端有可能在调用 CreateNamedPipe 和 ConnectNamedPipe 函数之间的时间间隔内成功连接到管道实例。如果发生这种情况,ConnectNamedPipe 返回零,GetLastError 返回 ERROR_PIPE_CONNECTED。

所以需要使用下面的代码来判断连接是否成功。

BOOL fConnected = ConnectNamedPipe(hPipe, NULL) ? 
         TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); 

参考:https://docs.microsoft.com/en-us/windows/win32/ipc/multithreaded-pipe-server