CreatePipe()等函数创建管道来操纵控制台

来源:互联网 发布:简易浏览器源码 编辑:程序博客网 时间:2024/06/08 18:52

#include <stdio.h> 
#include <windows.h> 
  
#define BUFSIZE 4096 
  
HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup, 
   hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup, 
   hInputFile, hStdout; 
  
BOOL CreateChildProcess(VOID); 
VOID WriteToPipe(VOID); 
VOID ReadFromPipe(VOID); 
VOID ErrorExit(LPTSTR); 
VOID ErrMsg(LPTSTRBOOL); 
  
DWORD main(int argc, char *argv[]) 
   SECURITY_ATTRIBUTES saAttr; 
   BOOL fSuccess; 
  
// Set the bInheritHandle flag so pipe handles are inherited. 
  
   saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
   saAttr.bInheritHandle = TRUE; 
   saAttr.lpSecurityDescriptor = NULL; 
  
// Get the handle to the current STDOUT. 
  
   hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
  
// Create a pipe for the child process's STDOUT. 
  
   if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) 
      ErrorExit("Stdout pipe creation failed\n"); 
  
// Create noninheritable read handle and close the inheritable read 
// handle. 
 
    fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
        GetCurrentProcess(), &hChildStdoutRdDup , 0,
        FALSE,
        DUPLICATE_SAME_ACCESS);
    if( !fSuccess )
        ErrorExit("DuplicateHandle failed");
    CloseHandle(hChildStdoutRd);
 
// Create a pipe for the child process's STDIN. 
  
   if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) 
      ErrorExit("Stdin pipe creation failed\n"); 
  
// Duplicate the write handle to the pipe so it is not inherited. 
  
   fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, 
      GetCurrentProcess(), &hChildStdinWrDup, 0, 
      FALSE,                  // not inherited 
      DUPLICATE_SAME_ACCESS); 
   if (! fSuccess) 
      ErrorExit("DuplicateHandle failed"); 
  
   CloseHandle(hChildStdinWr); 
  
// Now create the child process. 
    
   fSuccess = CreateChildProcess();
   if (! fSuccess) 
      ErrorExit("Create process failed"); 
 
// Get a handle to the parent's input file. 
  
   if (argc == 1) 
      ErrorExit("Please specify an input file");
 
   hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL, 
      OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); 
  
   if (hInputFile == INVALID_HANDLE_VALUE) 
      ErrorExit("CreateFile failed\n"); 
  
// Write to pipe that is the standard input for a child process. 
  
   WriteToPipe(); 
  
// Read from pipe that is the standard output for child process. 
  
   ReadFromPipe(); 
  
   return 0; 
  
BOOL CreateChildProcess() 
   PROCESS_INFORMATION piProcInfo; 
   STARTUPINFO siStartInfo;
   BOOL bFuncRetn = FALSE; 
  
// Set up members of the PROCESS_INFORMATION structure. 
  
   ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
  
// Set up members of the STARTUPINFO structure. 
  
   ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
   siStartInfo.cb = sizeof(STARTUPINFO); 
   siStartInfo.hStdError = hChildStdoutWr;
   siStartInfo.hStdOutput = hChildStdoutWr;
   siStartInfo.hStdInput = hChildStdinRd;
   siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
  
// Create the child process. 
     
   bFuncRetn = CreateProcess(NULL, 
      "child",       // 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 (bFuncRetn == 0) 
      ErrorExit("CreateProcess failed");
   else 
   {
      CloseHandle(piProcInfo.hProcess);
      CloseHandle(piProcInfo.hThread);
      return bFuncRetn;
   }
}
  
VOID WriteToPipe(VOID
   DWORD dwRead, dwWritten; 
   CHAR chBuf[BUFSIZE]; 
  
// Read from a file and write its contents to a pipe. 
  
   for (;;) 
   
      if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) || 
         dwRead == 0) break
      if (! WriteFile(hChildStdinWrDup, chBuf, dwRead, 
         &dwWritten, NULL)) break
   
  
// Close the pipe handle so the child process stops reading. 
  
   if (! CloseHandle(hChildStdinWrDup)) 
      ErrorExit("Close pipe failed"); 
  
VOID ReadFromPipe(VOID
   DWORD dwRead, dwWritten; 
   CHAR chBuf[BUFSIZE]; 
 
// Close the write end of the pipe before reading from the 
// read end of the pipe. 
  
   if (!CloseHandle(hChildStdoutWr)) 
      ErrorExit("CloseHandle failed"); 
  
// Read output from the child process, and write to parent's STDOUT. 
  
   for (;;) 
   
      if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead, 
         NULL) || dwRead == 0) break
      if (! WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL)) 
         break
   
  
VOID ErrorExit (LPTSTR lpszMessage) 
   fprintf(stderr, "%s\n", lpszMessage); 
   ExitProcess(0); 
}
原创粉丝点击