程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++裡面執行一個exe文件,匿名管道,exe管道

c++裡面執行一個exe文件,匿名管道,exe管道

編輯:C++入門知識

c++裡面執行一個exe文件,匿名管道,exe管道


操作系統的實驗要用到管道. 管道(Pipe)實際是用於進程間通信的一段共享內存,創建管道的進程稱為管道服務器,連接到一個管道的進程為管道客戶機。一個進程在向管道寫入數據後,另一進程就可以從管道的另一端將其讀取出來。匿名管道(Anonymous Pipes)是在父進程和子進程間單向傳輸數據的一種未命名的管道,只能在本地計算機中使用,而不可用於網絡間的通信。   匿名管道實施細則   匿名管道由CreatePipe()函數創建,該函數在創建匿名管道的同時返回兩個句柄:管道讀句柄和管道寫句柄。CreatePipe()的函數原型為:     BOOL CreatePipe(PHANDLE hReadPipe, // 指向讀句柄的指針    PHANDLE hWritePipe, // 指向寫句柄的指針    LPSECURITY_ATTRIBUTES lpPipeAttributes, // 指向安全屬性的指針    DWORD nSize // 管道大小   );   通過hReadPipe和hWritePipe所指向的句柄可分別以只讀、只寫的方式去訪問管道。  匿名管道並不支持異步讀、寫操作,這也就意味著不能在匿名管道中使用ReadFileEx()和WriteFileEx(),而且ReadFile()和WriteFile()中的lpOverLapped參數也將被忽略。匿名管道將在讀、寫句柄都被關閉後退出,也可以在進程中調用CloseHandle()函數來關閉此句柄。 1.如果只想得到子進程的結果則可以只創建一個管道,然後ReadFile()得到輸出就行了。 如下:  STARTUPINFO si;   PROCESS_INFORMATION pi;   char ReadBuf[100];   DWORD ReadNum;   HANDLE hRead; // 管道讀句柄   HANDLE hWrite; // 管道寫句柄   BOOL bRet = CreatePipe(&hRead, &hWrite, NULL, 0); // 創建匿名管道   if (bRet == TRUE)    printf("成功創建匿名管道!\n");   else    printf("創建匿名管道失敗,錯誤代碼:%d\n", GetLastError());    // 得到本進程的當前標准輸出    HANDLE hTemp = GetStdHandle(STD_OUTPUT_HANDLE);    // 設置標准輸出到匿名管道    SetStdHandle(STD_OUTPUT_HANDLE, hWrite);    GetStartupInfo(&si); // 獲取本進程的STARTUPINFO結構信息    bRet = CreateProcess(NULL, "Client.exe", NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi); // 創建子進程    SetStdHandle(STD_OUTPUT_HANDLE, hTemp); // 恢復本進程的標准輸出    if (bRet == TRUE) // 輸入信息     printf("成功創建子進程!\n");    else     printf("創建子進程失敗,錯誤代碼:%d\n", GetLastError());     CloseHandle(hWrite); // 關閉寫句柄     // 讀管道直至管道關閉     while (ReadFile(hRead, ReadBuf, 100, &ReadNum, NULL))     {      ReadBuf[ReadNum] = '\0';      printf("從管道[%s]讀取%d字節數據\n", ReadBuf, ReadNum);     }     if (GetLastError() == ERROR_BROKEN_PIPE) // 輸出信息      printf("管道被子進程關閉\n");     else      printf("讀數據錯誤,錯誤代碼:%d\n", GetLastError());   2.如果要想向子進程輸入數據則要為子進程的標准輸入也創建一個管道.再用WriteFile()輸入。 #include "Windows.h" #include "stdio.h" void main() { SECURITY_ATTRIBUTES sa,sa2; HANDLE hInputRead,hInputWrite; HANDLE hOutputRead,hOutputWrite; 
sa.nLength = sizeof(SECURITY_ATTRIBUTES);  sa.lpSecurityDescriptor = NULL;  sa.bInheritHandle = TRUE;    if (!CreatePipe(&hOutputRead,&hOutputWrite,&sa,0))  { printf("Error On CreatePipe1"); return; }  sa2.nLength = sizeof(SECURITY_ATTRIBUTES);  sa2.lpSecurityDescriptor = NULL; 
 sa2.bInheritHandle = TRUE;  if (!CreatePipe(&hInputRead,&hInputWrite,&sa2,0))  { printf("Error On CreatePipe2");  return;  } 
 STARTUPINFO si;  PROCESS_INFORMATION pi;  si.cb = sizeof(STARTUPINFO);  GetStartupInfo(&si);  si.hStdError = hOutputWrite; ///  si.hStdOutput = hOutputWrite; ///寫句柄賦予標准輸出(或標准錯誤)句柄  si.hStdInput = hInputRead; ///  //當父進程向子進程發送數據時,用SetStdHandle()  //將管道的讀句柄賦予標准輸入句柄;在從子進程接收數據時,  //則用SetStdHandle()將管道的寫句柄賦予標准輸出(或標准錯誤)句柄。  //然後,父進程可以調用進程創建函數CreateProcess()生成子進程。 //  如果父進程要發送數據到子進程,父進程可調用WriteFile() //  將數據寫入到管道(傳遞管道寫句柄給函數),子進程則調用GetStdHandle() //  取得管道的讀句柄,將該句柄傳入ReadFile()後從管道讀取數據。  si.wShowWindow = SW_HIDE;  si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;  DWORD dwWritten;  if (!CreateProcess(NULL,"c:\\windows\\system32\\cmd.exe ",NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))  { printf("Error On CreateProcess");  return;  } 
 CloseHandle(hInputRead);  CloseHandle(hOutputWrite);  char szInPut[20] = "dir\r\n ";  // 父進程向子進程發送數據,輸入  WriteFile(hInputWrite, szInPut, strlen(szInPut), &dwWritten, NULL);  char buffer[4096] = {0};  DWORD bytesRead;  // 父進程向子進程得到數據,輸出   while (true)  { 
  if(ReadFile(hOutputRead,buffer,4095,&bytesRead,NULL) == NULL) 
 { break;  }     printf(buffer);   Sleep(500);  } 
 CloseHandle(hInputWrite);  CloseHandle(hOutputRead);}  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved