Анонимные каналы: ReadFile в родительском процессе продолжает ждать, когда дочерний процесс будет убит

У меня есть программа, в которой родительский процесс порождает дочерний процесс, а затем связывается с ним.

Родительский процесс — это приложение VB, а дочерний процесс — это консольное приложение C#.

Родительский процесс (на данный момент удалена обработка ошибок):

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

Затем я использую WriteFile и ReadFile для записи и чтения в дочерний процесс.

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

Дочерний процесс (консольное приложение С#):

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();

Связь здесь работает, как и ожидалось. Я умею читать и писать успешно.

Когда родительский процесс закрывается, операция чтения в дочернем процессе возвращает значение false. Но когда дочерний процесс уничтожает себя (как показано ниже), родительский процесс продолжает ждать ReadFile. Почему это происходит ?

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();

Я внимательно следил за этим примером msdn: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx


person ykhandel    schedule 27.12.2016    source источник


Ответы (1)


Я нашел то, чего не хватало.

Мне нужно закрыть дескрипторы дочернего процесса после его создания.

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