Перенаправление вывода CMD.exe и ввода в c-каналы

Im пытается распечатать вывод и ввод команд cmd, полученных в stdout, как это сделал бы обычный cmd.exe. Я мог бы использовать функцию _popen но когда я запускаю программу, такую ​​как Python или Powershell, она не работает. Поэтому мне нужен вывод дочернего процесса и вы можете отправлять команды дочернему процессу.

здесь есть простой вопрос

Поэтому я изменил код из этой ссылки, чтобы выглядеть так:

 void WriteToPipe(char* command){ DWORD dwRead, dwWritten; BOOL bSuccess = FALSE; bSuccess = WriteFile(g_hChildStd_IN_Wr, command, strlen(command), &dwWritten, NULL); // Close the pipe handle so the child process stops reading. if (!CloseHandle(g_hChildStd_IN_Wr)) ErrorExit(TEXT("StdInWr CloseHandle")); } void ReadFromPipe(void){ DWORD dwRead, dwWritten; CHAR chBuf[BUFSIZE]; BOOL bSuccess = FALSE; HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE); bSuccess = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL); bSuccess = WriteFile(hParentStdOut, chBuf, dwRead, &dwWritten, NULL); //bSuccess = PeekNamedPipe(g_hChildStd_OUT_Rd, NULL, BUFSIZE, &dwRead, &dwTotalAvailBytes, &dwBytesLeft); } 

основной цикл выглядит так:

 CreateChildProcess("C:\\Python27\\python.exe"); char input_buffer[100] = { 0 }; while (1){ fgets(input_buffer, 99, stdin); WriteToPipe(input_buffer); ReadFromPipe(); } 

все остальное (из кода) оставалось неизменным.

Теперь моя проблема в том, что я хочу вводить несколько команд в один и тот же процесс, но есть функция CloseHandle в WriteToPipe, после закрытия дескриптора я не могу ввести больше команд.

Как получить действительную HANDLE, чтобы написать более 1 команды для процесса?

поместите ReadFromPipe () в отдельный stream; мой код здесь – мусор, но это рабочий код, он предназначен только для тестирования.

 #include  #include  #include  #include  #define BUFSIZE 4096 HANDLE g_hChildStd_IN_Rd = NULL; HANDLE g_hChildStd_IN_Wr = NULL; HANDLE g_hChildStd_OUT_Rd = NULL; HANDLE g_hChildStd_OUT_Wr = NULL; HANDLE g_hInputFile = NULL; int CreateChildProcess(TCHAR *szCmdline); void PrintError(char *text,int err); int InitPipes(); int WriteToPipe(char* command){ DWORD dwRead, dwWritten; BOOL bSuccess = FALSE; SetLastError(0); WriteFile(g_hChildStd_IN_Wr, command, strlen(command), &dwWritten, NULL); bSuccess=GetLastError(); PrintError("WriteToPipe",bSuccess); return (bSuccess==0)||(bSuccess==ERROR_IO_PENDING); } int ReadFromPipe(void){ DWORD dwRead, dwWritten; CHAR chBuf[BUFSIZE]; BOOL bSuccess = FALSE; HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE); SetLastError(0); while( ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL) && WriteFile(hParentStdOut, chBuf, dwRead, &dwWritten, NULL) ); bSuccess=GetLastError(); PrintError("ReadFromPipe",bSuccess); return (bSuccess==0)||(bSuccess==ERROR_IO_PENDING); } HANDLE hThread; int __stdcall ThreadProc(int arg){ while(ReadFromPipe()) ; return 0; } int main(){ char input_buffer[100] = { 0 }; if(!InitPipes()){ printf("Failed to CreatePipes\n"); return -1; } if(!CreateChildProcess("cmd.exe")){ printf("Failed to create child process\n"); return -2; } hThread=CreateThread(NULL,0,ThreadProc,NULL,0,NULL); while (1){ fgets(input_buffer, 99, stdin); if(!WriteToPipe(input_buffer)) break; } printf("Program terminated\n"); return 0; } int CreateChildProcess(TCHAR *szCmdline){ PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; BOOL bSuccess = FALSE; // 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; // Create the child process. bSuccess = CreateProcess(NULL, szCmdline, // command line NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited 0, // creation flags NULL, // use parent's environment NULL, // use parent's current directory &siStartInfo, // STARTUPINFO pointer &piProcInfo); // receives PROCESS_INFORMATION // If an error occurs, exit the application. if ( bSuccess ){ // 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(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); } return bSuccess; } int InitPipes(){ SECURITY_ATTRIBUTES saAttr; // Set the bInheritHandle flag so pipe handles are inherited. saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) ) return 0; if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) ) return 0; if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) return 0; if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) ) return 0; return 1; } void PrintError(char *text,int err){ DWORD retSize; LPTSTR pTemp=NULL; if(!err) return; retSize=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER| FORMAT_MESSAGE_FROM_SYSTEM| FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, err, LANG_NEUTRAL, (LPTSTR)&pTemp, 0, NULL ); if(pTemp) printf("%s: %s\n",text,pTemp); LocalFree((HLOCAL)pTemp); return ; } в #include  #include  #include  #include  #define BUFSIZE 4096 HANDLE g_hChildStd_IN_Rd = NULL; HANDLE g_hChildStd_IN_Wr = NULL; HANDLE g_hChildStd_OUT_Rd = NULL; HANDLE g_hChildStd_OUT_Wr = NULL; HANDLE g_hInputFile = NULL; int CreateChildProcess(TCHAR *szCmdline); void PrintError(char *text,int err); int InitPipes(); int WriteToPipe(char* command){ DWORD dwRead, dwWritten; BOOL bSuccess = FALSE; SetLastError(0); WriteFile(g_hChildStd_IN_Wr, command, strlen(command), &dwWritten, NULL); bSuccess=GetLastError(); PrintError("WriteToPipe",bSuccess); return (bSuccess==0)||(bSuccess==ERROR_IO_PENDING); } int ReadFromPipe(void){ DWORD dwRead, dwWritten; CHAR chBuf[BUFSIZE]; BOOL bSuccess = FALSE; HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE); SetLastError(0); while( ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL) && WriteFile(hParentStdOut, chBuf, dwRead, &dwWritten, NULL) ); bSuccess=GetLastError(); PrintError("ReadFromPipe",bSuccess); return (bSuccess==0)||(bSuccess==ERROR_IO_PENDING); } HANDLE hThread; int __stdcall ThreadProc(int arg){ while(ReadFromPipe()) ; return 0; } int main(){ char input_buffer[100] = { 0 }; if(!InitPipes()){ printf("Failed to CreatePipes\n"); return -1; } if(!CreateChildProcess("cmd.exe")){ printf("Failed to create child process\n"); return -2; } hThread=CreateThread(NULL,0,ThreadProc,NULL,0,NULL); while (1){ fgets(input_buffer, 99, stdin); if(!WriteToPipe(input_buffer)) break; } printf("Program terminated\n"); return 0; } int CreateChildProcess(TCHAR *szCmdline){ PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; BOOL bSuccess = FALSE; // 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; // Create the child process. bSuccess = CreateProcess(NULL, szCmdline, // command line NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited 0, // creation flags NULL, // use parent's environment NULL, // use parent's current directory &siStartInfo, // STARTUPINFO pointer &piProcInfo); // receives PROCESS_INFORMATION // If an error occurs, exit the application. if ( bSuccess ){ // 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(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); } return bSuccess; } int InitPipes(){ SECURITY_ATTRIBUTES saAttr; // Set the bInheritHandle flag so pipe handles are inherited. saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) ) return 0; if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) ) return 0; if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) return 0; if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) ) return 0; return 1; } void PrintError(char *text,int err){ DWORD retSize; LPTSTR pTemp=NULL; if(!err) return; retSize=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER| FORMAT_MESSAGE_FROM_SYSTEM| FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, err, LANG_NEUTRAL, (LPTSTR)&pTemp, 0, NULL ); if(pTemp) printf("%s: %s\n",text,pTemp); LocalFree((HLOCAL)pTemp); return ; } 
 int WriteToPipe(char* command){ DWORD dwRead, dwWritten; BOOL bSuccess = FALSE; bSuccess = WriteFile(g_hChildStd_IN_Wr, command, strlen(command), &dwWritten, NULL); return bSuccess ; } 

закройте дескриптор функции main (), так как g_hChildStd_IN_Wr является глобальным. также, return bSuccess; уведомлять вас, если запись в трубу преуспела