我有一个C#客户端应用程序,它使用管道连接到一个C++服务器应用程序。当我尝试连接时,会出现错误:System.UnauthorizedAccessException:拒绝访问路径。
在查找此问题时,我发现可以通过创建PipeSecurity对象并添加PipeAccessRule来解决它。但是,这仅适用于服务器也是C#应用程序的情况。
如果我的服务器是C++应用程序,你有什么解决办法吗?
我已经搜索过了,但找不到解决方案。
C#:
int timeOut = 500;
NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", pipeName, PipeDirection.Out, PipeOptions.Asynchronous);
pipeStream.Connect(timeOut);
byte[] buffer = Encoding.UTF8.GetBytes(sendStr);
pipeStream.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(AsyncSend), pipeStream);
C++:
_hPipe = ::CreateNamedPipe(configurePipeName(getPipeName()).c_str(),
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS,
1,
bufferSize,
bufferSize,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);
if (_hPipe == INVALID_HANDLE_VALUE)
{
logStream << "CreateNamedPipe failed for " << sys::OperatingSystem::getLastErrorMessage() << blog::over;
return;
}
HANDLE ioEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
overlapped.hEvent = ioEvent;
assert(overlapped.hEvent);
if (ioEvent == INVALID_HANDLE_VALUE)
{
logStream << "CreateEvent failed for " << sys::OperatingSystem::getLastErrorMessage() << blog::over;
return;
}
while (!terminating())
{
BOOL connected = false;
DWORD waitMessage;
DWORD timeOut = 700;
if (!::ConnectNamedPipe(_hPipe, &overlapped))
{
switch (::GetLastError())
{
case ERROR_PIPE_CONNECTED:
connected = true;
break;
case ERROR_IO_PENDING:
waitMessage = ::WaitForSingleObject(overlapped.hEvent, timeOut);
if (waitMessage == WAIT_OBJECT_0)
{
DWORD dwIgnore;
BOOL conn = (::GetOverlappedResult(_hPipe, &overlapped, &dwIgnore, TRUE));
if (conn)
connected = true;
else
logStream << "ConnectedNamedPipe reported an error: " << sys::OperatingSystem::getLastErrorMessage() << blog::over;
}
else
::CancelIo(_hPipe);
break;
default:
logStream << "ConnectedNamedPipe reported an error: " << sys::OperatingSystem::getLastErrorMessage() << blog::over;
}
}
if(connected)
{
if (::ReadFile(_hPipe, buffer, sizeof(buffer) - 1, &size, NULL))
{
buffer[size] = '\0';
std::string receivedMessage(buffer);
// if message is received from client, setdirty to call detectDisplay.
if (clientUniqueMessage.compare(receivedMessage) == 0)
setDirty();
else
logStream << "Incoming message from client does not match with the expected message." << blog::over;
}
else
logStream << "ReadFile failed. " << sys::OperatingSystem::getLastErrorMessage() << blog::over;
}
::DisconnectNamedPipe(_hPipe);
}
}