Я работаю с приложением, которое предлагает api, чтобы упростить создание сценариев. В принципе, когда вы пишете допустимый ввод, он выдает ответ. Я хотел бы использовать этот вывод отправляет больше входного сигнала и т.д .:Перенаправление ввода-вывода из дочернего процесса с использованием труб - winapi
Input: <nodes>
Output: 1, 56, 23
Input <56>
Output: "Apple"
То, что я хотел бы сделать, это программа, которая записывает в целевой процесс STDIN, а затем читает вывод от его STDOUT. Чтобы сделать это, я в основном взял код оттуда:
Creating a Child Process with Redirected Input and Output (Windows) - MSDN
Единственная проблема заключается в том, что для того, чтобы читать из дочернего процесса, сначала я должен закрыть дескриптор моего родительского процесса, используемого для записи это означает, что я не могу использовать вывод из дочернего процесса, чтобы написать ему больше материала.
Вот упрощенный код взят из MSDN:
#include <Windows.h>
#include <string>
using std::string;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
#define BUFSIZE 4096
void WriteToPipe(string msg);
void ReadFromPipe(void);
int main()
{
/*
* CREATE PIPES
*/
SECURITY_ATTRIBUTES saAttr;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Create pipes for the child process's STDOUT and STDIN,
// ensures both handle are not inherited
CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0);
SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0);
CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0);
SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0);
/*
* CREATE CHILD PROCESS
*/
TCHAR szCmdline[]=TEXT("target.exe");
STARTUPINFO siStartInfo;
PROCESS_INFORMATION piProcInfo;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
// Set up members of the STARTUPINFO structure.
// This structure specifies the STDIN and STDOUT handles for redirection.
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = g_hChildStd_OUT_Wr;
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
siStartInfo.hStdInput = g_hChildStd_IN_Rd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
CreateProcess(NULL, szCmdline, NULL, NULL, TRUE, 0,
NULL, NULL, &siStartInfo, &piProcInfo);
// Close handles to the child process and its primary thread.
// Some applications might keep these handles to monitor the status
// of the child process, for example.
CloseHandle(g_hChildStd_OUT_Wr);
CloseHandle(g_hChildStd_IN_Rd);
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
/*
* ACTUAL APPLICATION
*/
WriteToPipe("<nodes>\n");
// Need to close the handle before reading
CloseHandle(g_hChildStd_IN_Wr); // PROBLEM HERE
ReadFromPipe();
WriteToPipe("<56>\n"); // I can't, as I have released the handle already
system("pause");
return 0;
}
void WriteToPipe(string msg)
{
WriteFile(g_hChildStd_IN_Wr, msg.c_str(), msg.size(), NULL, NULL);
}
void ReadFromPipe(void)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
BOOL bSuccess = FALSE;
HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
for (;;)
{
bSuccess = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
if(! bSuccess || dwRead == 0) break;
bSuccess = WriteFile(hParentStdOut, chBuf, dwRead, &dwWritten, NULL);
if (! bSuccess) break;
}
}
Проблема возникает из линии:
CloseHandle(g_hChildStd_IN_Wr);
Либо я оставил его там, и я не буду в состоянии написать мой дочерний процесс после того, как я прочитал его один раз, или я удаляю его, а затем ReadFromPipe застрял в тупике.
Любая помощь будет оценена, спасибо!
«Чтобы прочитать из дочернего процесса, мне сначала нужно закрыть дескриптор моего родительского процесса, который используется для записи:« Нет, нет, где-то есть способ сделать это. Я сделал это один раз, я просто должен запомнить, как –
Если я удалю строку «CloseHandle (g_hChildStd_IN_Wr);», программа застрянет в ReadFromPipe по строке «bSuccess = ReadFile (g_hChildStd_OUT_Rd, chBuf, BUFSIZE, & dwRead, NULL); , Хотя я не совсем уверен, почему это происходит, оно делает ... любое решение? – MyUsername112358
Да, это то, что я только что пробовал! Но по какой-то причине «result = PeekNamedPipe (g_hChildStd_OUT_Rd, chBuf, BUFSIZE, & dwRead, & dwAvailableBytes, & dwBytesLeft);» всегда выполняется, но dwRead, dwAvailableBytes и dwBytesLeft всегда получают значение 0, есть ли байты для чтения или нет. Я буду больше смотреть на него, может быть, я что-то пропустил ... – MyUsername112358