I am working on a project where I am interacting between the components of VC++ (Server) and C# Client.
The C# component is been triggered by VC++ and further interactions happens between these components over Control Pipes.
The Control pipe is created at the VC++ as follows:
StartNamedPipeServer(const wchar_t* wszParametersXML)
{
m_hServerPipe = ::CreateNamedPipe(m_wszServerPipe, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, MAX_PATH, MAX_PATH, 0, NULL);
if(m_hServerPipe!=INVALID_HANDLE_VALUE)
{
::ConnectNamedPipe(m_hServerPipe, NULL);
}
DWORD dwWrite=0;
::WriteFile(m_hServerPipe, szFilePath, strlen(szFilePath), &dwWrite, NULL);
return 0;
}
The control pipe is created and connected fine. At the C# end the data is received without any problem and C# (Client) writes back to the same pipe with "wait" and "proceed" messages as below.
while (true)
{
using (NamedPipeClientStream ClientPipeStream = new NamedPipeClientStream(".", NamedClientPipe, PipeDirection.InOut))
{
while (true)
{
try
{
ClientPipeStream.Connect(1000);
break;
}
catch
{
continue;
}
}
StreamReader ClientStream = new StreamReader(ClientPipeStream);
char[] param = new char[260];
while (ClientStream.Peek() >= 0)
{
ClientStream.Read(param, 0, param.Length);
}
using (StreamWriter ServerStreamWriter = new StreamWriter(ClientPipeStream))
{
try
{
ServerStreamWriter.AutoFlush = true;
ServerStreamWriter.WriteLine("wait");
StartProcessing(modelFolderPath, mailslotName, ControlPipeName);
ServerStreamWriter.WriteLine("proceed");
System.Threading.Thread.Sleep(1000);
}
catch (Exception ex)
{
ServerStreamWriter.WriteLine("proceed");
System.Threading.Thread.Sleep(1000);
retvalue = FAILURE;
}
}
}
}
VC++ reads the messages for further processing as below.
ReadNamedPipeServer()
{
char szClientUpdate[100];
BOOL bSuccess=FALSE;
for (;;)
{
DWORD dwBytesAvail = 0;
if(!::PeekNamedPipe(m_hServerPipe, NULL, 0, NULL, &dwBytesAvail, NULL) || dwBytesAvail > 0)
{
DWORD dwRead=0;
bSuccess = ::ReadFile(m_hServerPipe, szClientUpdate, sizeof(szClientUpdate), &dwRead, NULL);
if (bSuccess)
{
if(strncmp(szClientUpdate, "wait", 4) == 0)
{
return 1;
}
if(strncmp(szClientUpdate, "proceed", 7) == 0)
{
return 0;
}
}
}
Need the experts suggestions and design changes if anything required here.
What I have tried:
The ReadNamedPipe server works fine and the messages "wait" and "proceed" are read fine. but sometimes, when "proceed" is written, the pipe is not been read at the VC++ ReadNamedPipeServer() method and the program goes to an infinite loop and hangs the application flow.(This happens in some specific machines like Win 10 64Bit and sometimes in Win7 64bit machines).