使用CreateProcess函数实现隐秘的程序调用之二:使用匿名管道

来源:互联网 发布:python网络爬虫实战pdf 编辑:程序博客网 时间:2024/05/07 07:01

// 所有原创文章转载请注明作者及链接
// 
blackboycpp(AT)gmail.com
// QQ群: 135202158


前一篇文章已经实现了基本功能,但有一个问题,就是需要读写硬盘上的文件。

如果实在不想读写文件,可以将进程启动信息中的输出重定向到一个匿名管道,再从管道中读取进程的输出即可。

 

[cpp] view plain copy
 print?
  1. void CCPTFDlg::OnBnClickedBtnPing()  
  2. {  
  3.     UpdateData(TRUE);  
  4.   
  5.     BOOL bRet = FALSE;  
  6.     // 拼接要执行的命令行,如"ping.exe www.google.com"  
  7.     CString sAddr;  
  8.     GetDlgItem(IDC_EDIT_ADDR)->GetWindowText(sAddr);  
  9.     CString sCmdLine = _T("ping.exe ") + sAddr;  
  10.       
  11.     // 设置管道句柄安全属性  
  12.     SECURITY_ATTRIBUTES sa;  
  13.     ::ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));  
  14.     sa.nLength = sizeof(SECURITY_ATTRIBUTES);  
  15.     sa.bInheritHandle = TRUE;       // 必须为TRUE  
  16.     sa.lpSecurityDescriptor = NULL;  
  17.   
  18.     // 创建匿名管道  
  19.     HANDLE hPipeRead, hPipeWrite;  
  20.     bRet = ::CreatePipe(&hPipeRead, &hPipeWrite, &sa, 0);  
  21.     ASSERT(bRet == TRUE);  
  22.   
  23.     // 设置进程的启动信息,这是一个输入参数  
  24.     STARTUPINFO si;  
  25.     ::ZeroMemory(&si, sizeof(STARTUPINFO));  
  26.     si.cb = sizeof(STARTUPINFO);  
  27.     si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;   // 这个必须设置,否则仍将显示窗口  
  28.     si.hStdOutput = hPipeWrite; // 设置为写管道  
  29.     si.wShowWindow = SW_HIDE;   // 不显示窗口  
  30.   
  31.     // 设置进程信息,这是一个输出参数。我们需要从这个结构中取得创建成功的进程及其主线程的句柄  
  32.     PROCESS_INFORMATION pi;  
  33.     ::ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));  
  34.       
  35.     // 使用刚才设置的各个参数创建隐秘的进程  
  36.     // 此进程将把ping程序运行的结果写到管道   
  37.     bRet = ::CreateProcess(NULL, sCmdLine.GetBuffer(), NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi);  
  38.     ASSERT(bRet == TRUE);  
  39.       
  40.     // 等待进程对象的结束。即等待ping程序运行完成  
  41.     ::WaitForSingleObject(pi.hProcess, INFINITE);  
  42.     // 结束进程  
  43.     ::CloseHandle(pi.hProcess);  
  44.     ::CloseHandle(pi.hThread);  
  45.   
  46.     // 从管道读取上述进程的输出,并显示于界面  
  47.     char buffer[1024] = {0};  
  48.     DWORD dwBytesRead;  
  49.     bRet = ::ReadFile(hPipeRead, buffer, 1023, &dwBytesRead, 0);  
  50.     ASSERT(bRet == TRUE);  
  51.     ASSERT(dwBytesRead > 0);  
  52.     GetDlgItem(IDC_EDIT_OUT)->SetWindowText(CString(buffer));  
  53.   
  54.     // 关闭管道  
  55.     ::CloseHandle(hPipeRead);  
  56.     ::CloseHandle(hPipeWrite);  
  57. }  

界面和其余部分与上一篇提到的小例子相同。

0 0