重定向CMD.exe输出并通过管道输入c

我试图打印输出和输入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(); } 

其他一切(来自代码)保持不变。

现在我的问题是,我想输入多个命令到同一个进程,但WriteToPipe中有一个CloseHandlefunction,在句柄关闭后我无法输入更多命令。

如何获得一个有效的HANDLE来向进程写入多个命令?

把ReadFromPipe()放在一个单独的Thread中; 我的代码在这里是一个垃圾,但它是工作代码,它仅用于测试目的。

 #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; 如果写入管道成功,则通知您