现在的位置: 首页 > 综合 > 正文

总结两种创建匿名管道来截获控制台命令的方法

2018年05月01日 ⁄ 综合 ⁄ 共 2031字 ⁄ 字号 评论关闭

第一种为FILE *_popen(   const char *command,   const char *mode); 第一个参数直接传命令,返回端直接为管道的句柄,用fget来提取文件信息。

贴出关键代码:

WideCharToMultiByte(CP_ACP, 0, strCmmdLine.GetBuffer(), strCmmdLine.GetLength(), path, MAX_PATH-1, NULL, NULL);

//注意,命令行参数必须为ASCII字符
  if( (child_output = _popen(path, "rt" )) == NULL )
   return 1;

  while(!feof( child_output ) )
  {
    if( fgets( psBuffer, 1023, child_output ))
    {
        // 将子进程的标准输出写入管道,提供给自己的父进程
        // 格式是先写数据块长度(0表示结束),再写数据块内容
        pInfo->strRes += psBuffer;
    }
  }
   // 写“0”表示所有数据都已写完
  return _pclose( child_output );

 

第二种较为复杂,但设置上可有多种选择,如开启子进程后可选择将子进程隐藏显示

创建管道原型函数,目的就是开启一个匿名管道,同时获取到管道的读写句柄

BOOL WINAPI CreatePipe(
  __out         PHANDLE hReadPipe,
  __out         PHANDLE hWritePipe,
  __in          LPSECURITY_ATTRIBUTES lpPipeAttributes,
  __in          DWORD nSize
);

 

传命令行函数

CreateProcess()

关键代码:

 SECURITY_ATTRIBUTES saAttr;
   saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
   saAttr.bInheritHandle = TRUE;                        //注意,这一行一定要为TRUE,子进程可以继承句柄设置
   saAttr.lpSecurityDescriptor = NULL;
   if(!CreatePipe(&(pInfo->hRead), &(pInfo->hWrite),&saAttr,0))
   {
    return 1;
   }

  STARTUPINFO siStartInfo;
  GetStartupInfo(&siStartInfo);                 //通过这个函数省了不少事    
  siStartInfo.hStdOutput = pInfo->hWrite;  //设置输出句柄
  siStartInfo.hStdError = pInfo->hWrite;  //设置错误句柄
   siStartInfo.cb = sizeof(STARTUPINFO);  //设置大小
   siStartInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
   siStartInfo.wShowWindow = SW_HIDE;
 

   PROCESS_INFORMATION piProcInfo;
   ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
   CString strCmmdLine;
   strCmmdLine =  "E:\\TestLoad.exe ";

 CreateProcess(NULL,      //第一个参数可为空,
  strCmmdLine.GetBuffer(),
  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
 char buf[1024] = {0};
 DWORD len;
 CloseHandle(pInfo->hWrite);       //注意,一定要在本端关闭句柄,否则子进程无法进行写操作
 while(ReadFile(pInfo->hRead, buf, 1023, &len, NULL))
 {
  pInfo->strRes += buf;
 }

 

抱歉!评论已关闭.