Anonymous pipes: ReadFile in parent process keeps on waiting when the child process is killed

345 views Asked by At

I have a program in which a parent process spawns off a child process and then communicates with it.

Parent process is a VB application and the child process is a C# console application.

Parent Process (Removed error handling for now):

Private Function InitialieExtConversionProcess() As Boolean

Dim lResult As Long
Dim SA As SECURITY_ATTRIBUTES
Dim sInfo As STARTUPINFO
Dim sCommandLine As String

SA.bInheritHandle = True

'Create the pipe that Hyperspace will write to
lResult = CreatePipe(m_pipeOut.hReadPipe, m_pipeOut.hWritePipe, SA, 0)

'Ensure that the read handle is not inherited
lResult = SetHandleInformation(m_pipeOut.hReadPipe, HANDLE_FLAG_INHERIT, 0)


'Create the pipe that Hyperspace will read from
lResult = CreatePipe(m_pipeIn.hReadPipe, m_pipeIn.hWritePipe, SA, 0)

'Ensure that the write handle is not inherited
lResult = SetHandleInformation(m_pipeIn.hWritePipe, HANDLE_FLAG_INHERIT, 0)

'Create the external process
sCommandLine = "some_path\ExtProcess.exe"
sInfo.hStdInput = m_pipeIn.hReadPipe
sInfo.hStdError = m_pipeOut.hWritePipe
sInfo.hStdOutput = m_pipeOut.hWritePipe
sInfo.dwFlags = STARTF_USESTDHANDLES
lResult = CreateProcess(0, sCommandLine, 0, 0, 1, CREATE_NO_WINDOW, 0, 0,   sInfo, m_pInfo)

InitialieExtConversionProcess = True

End Function

I then use WriteFile and ReadFile to write and read to child process

lResult = WriteFile(m_pipeIn.hWritePipe, sOutput, Len(sOutput), 0, 0)
...
lResult = ReadFile(m_pipeOut.hReadPipe, sInput, Len(sInput), 0, ByVal 0)

Child Process (C# console application):

IntPtr hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
IntPtr hInput = GetStdHandle(STD_INPUT_HANDLE);              
AnonymousPipeClientStream pipeClientRead = new     AnonymousPipeClientStream(PipeDirection.In, hInput.ToString());
AnonymousPipeClientStream pipeClientWrite = new AnonymousPipeClientStream(PipeDirection.Out, hOutput.ToString());

arr = new byte[300];
pipeClientRead.Read(arr, 0, 300);
...
arr = Encoding.ASCII.GetBytes(strResult);
pipeClientWrite.Write(arr, 0, arr.Length);
pipeClientWrite.Flush();

The communication is working as expected here. I am able to read and write successfully.

When the parent process is closed, the Read operation in child process returns false. But when the child process kills itself (like below), the parent process keeps on waiting on ReadFile. Why is this happening ?

arr = new byte[300];
pipeClientRead.Read(arr, 0, 300);
--->Environment.exit(1);<----
arr = Encoding.ASCII.GetBytes(strResult);
pipeClientWrite.Write(arr, 0, arr.Length);
pipeClientWrite.Flush();

I have closely followed this msdn example: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx

1

There are 1 answers

0
ykhandel On

I found what was misisng.

I need to close the handles of the child process after creating it.

lResult = CreateProcess(0, sCommandLine, 0, 0, 1, CREATE_NO_WINDOW, 0, 0,   sInfo, m_pInfo)
CloseHnadle(m_pipeIn.hReadPipe)
CloseHandle(m_pipeOut.hWritePipe)