VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 265|回复: 7

[已解决]创建进程后,怎么获取进程输出的字符串内容?

[复制链接]
05_avatar_middle
最佳答案
0 
online_vip 发表于 2021-8-18 00:06:03 | 显示全部楼层 |阅读模式
请问创建进程后,怎么获取进程输出的字符串内容?
最佳答案
51_avatar_small
2021-8-18 00:40:21
进程有窗口吗?还是命令行模式的?
如果是命令行的话可以使用管道接收命令行的输出




上一篇:说说此刻的一些想法
下一篇:请问怎么访问有账号密码的共享文件?
05_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2021-8-18 18:06:40 | 显示全部楼层
Syc 发表于 2021-8-18 00:40
进程有窗口吗?还是命令行模式的?
如果是命令行的话可以使用管道接收命令行的输出

命令行模式的
bcdedit这个命令

我在网上找了资料,使用匿名管道,但是不行。具体代码如下:

  1. BOOL COneKeyDlg::RunProcess(LPTSTR szCommandLine, LPTSTR szRetBuf, DWORD iRetBufLen, BOOL waitExit)
  2. {
  3.        
  4.         HANDLE hRead = INVALID_HANDLE_VALUE, hWrite = INVALID_HANDLE_VALUE;
  5.         STARTUPINFO si;
  6.         PROCESS_INFORMATION pi;

  7.         ZeroMemory(&si, sizeof(si));
  8.         ZeroMemory(&pi, sizeof(pi));

  9.         si.cb = sizeof(STARTUPINFO);
  10.         GetStartupInfo(&si);

  11.         BOOL bRet = NULL != szRetBuf && iRetBufLen > 0;

  12.         if (bRet)
  13.         {
  14.                 SECURITY_ATTRIBUTES sa;
  15.                 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  16.                 sa.lpSecurityDescriptor = NULL;
  17.                 sa.bInheritHandle = TRUE;

  18.                 if (!CreatePipe(&hRead, &hWrite, &sa, 0)) {
  19.                         MessageBox("创建管道失败");
  20.                         return FALSE;
  21.                 }

  22.                 si.hStdError = hWrite;
  23.                 si.hStdOutput = hWrite;
  24.         }

  25. //        si.wShowWindow = SW_HIDE;
  26.         si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;

  27.         if (CreateProcess(
  28.                 NULL,   //  指向一个NULL结尾的、用来指定可执行模块的宽字节字符串  
  29.                 szCommandLine, // 命令行字符串  
  30.                 NULL, //    指向一个SECURITY_ATTRIBUTES结构体,这个结构体决定是否返回的句柄可以被子进程继承。  
  31.                 NULL, //    如果lpProcessAttributes参数为空(NULL),那么句柄不能被继承。<同上>  
  32.                 false,//    指示新进程是否从调用进程处继承了句柄。   
  33.                 0,  //  指定附加的、用来控制优先类和进程的创建的标  
  34.                         //  CREATE_NEW_CONSOLE  新控制台打开子进程  
  35.                         //  CREATE_SUSPENDED    子进程创建后挂起,直到调用ResumeThread函数  
  36.                 NULL, //    指向一个新进程的环境块。如果此参数为空,新进程使用调用进程的环境  
  37.                 NULL, //    指定子进程的工作路径  
  38.                 &si, // 决定新进程的主窗体如何显示的STARTUPINFO结构体  
  39.                 &pi  // 接收新进程的识别信息的PROCESS_INFORMATION结构体  
  40.         ))
  41.         {
  42.                 if (waitExit)
  43.                 {
  44.                         // 等待进程结束
  45.                         WaitForSingleObject(pi.hProcess, INFINITE);
  46.                         DWORD dwRet = WaitForSingleObject(pi.hProcess, INFINITE);
  47.                         switch (dwRet)
  48.                         {
  49.                         case WAIT_TIMEOUT:
  50.                         case WAIT_FAILED:
  51.                                 return FALSE;
  52.                         }
  53.                 }
  54.                 //下面两行关闭句柄,解除本进程和新进程的关系,不然有可能不小心调用TerminateProcess函数关掉子进程  
  55.                 CloseHandle(pi.hProcess);
  56.                 CloseHandle(pi.hThread);

  57.                 if (bRet)
  58.                 {
  59.                         CloseHandle(hWrite); //如果hWrite句柄在这里关闭,错误码为109,管道已经关闭
  60.                         DWORD dwRead, dwAvail;
  61.                         if (!PeekNamedPipe(hRead, szRetBuf, 1, &dwRead, &dwAvail, NULL) || dwAvail <= 0)//PeekNamePipe用来预览一个管道中的数据,用来判断管道中是否为空
  62.                         {
  63.                                 CString str;
  64.                                 str.Format("错误码:%ld", GetLastError());
  65.                                 MessageBox(str);
  66.                                 CloseHandle(hRead);
  67.                                 return FALSE;
  68.                         }
  69.                         DWORD nReadedBytesCount = 0;
  70.                         DWORD nBytesRead = 0;
  71.                         DWORD dReadLen = 1024;
  72.                         while (true)
  73.                         {
  74.                                 if (dReadLen > iRetBufLen - nReadedBytesCount)
  75.                                 {
  76.                                         dReadLen = iRetBufLen - nReadedBytesCount;
  77.                                 }

  78.                                 if (!ReadFile(hRead, szRetBuf, dReadLen, &nBytesRead, NULL))
  79.                                 {
  80.                                         CString str;
  81.                                         str.Format("错误码:%ld", GetLastError());
  82.                                         MessageBox(str);
  83.                                         break;
  84.                                 }

  85.                                 nReadedBytesCount += nBytesRead;

  86.                                 if (nReadedBytesCount >= iRetBufLen)
  87.                                 {
  88.                                         break;
  89.                                 }
  90.                         }
  91.                         // CloseHandle(hWrite); //如果hWrite句柄在这里关闭,会导致ReadFile无限阻塞
  92.                         CloseHandle(hRead);
  93.                 }
  94.                 return TRUE;
  95.         }
  96.         if (bRet)
  97.         {
  98.                 CloseHandle(hRead);
  99.                 CloseHandle(hWrite);
  100.         }
  101.         return FALSE;
  102. }
复制代码
05_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2021-8-18 18:26:15 | 显示全部楼层
已经解决,大意了
CreateProcess的bInheritHandles参数要传TRUE
05_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2021-8-18 18:11:34 | 显示全部楼层
本帖最后由 coolhty 于 2021-8-18 18:17 编辑

如果CloseHandle(hWrite);放上面,ReadFile函数GetLastError()报错109
如果CloseHandler(hWrite);放下面,PeekNamedPipe函数GetLastError()报错183
51_avatar_middle
最佳答案
88 
online_admins 发表于 2021-8-18 00:40:21 | 显示全部楼层    本楼为最佳答案   
bestAnswer
进程有窗口吗?还是命令行模式的?
如果是命令行的话可以使用管道接收命令行的输出
50_avatar_middle
最佳答案
0 
在线会员 发表于 2021-8-18 19:21:06 | 显示全部楼层
Syc 发表于 2021-8-18 00:40
进程有窗口吗?还是命令行模式的?
如果是命令行的话可以使用管道接收命令行的输出

那我的是MFC程序怎么办?
05_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2021-8-18 22:37:52 | 显示全部楼层
specterks 发表于 2021-8-18 19:21
那我的是MFC程序怎么办?

被调用的进程是MFC程序吗?
50_avatar_middle
最佳答案
0 
在线会员 发表于 2021-8-20 10:43:02 | 显示全部楼层
coolhty 发表于 2021-8-18 22:37
被调用的进程是MFC程序吗?

就是MFC程序调用adb.exe进程,利用管道获取输出内容
但是网上查了好久的资料,不是CreateProcess失败就是报错
所以才来VC驿站找资料
谢谢
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号-4 )|网站地图wx_jqr

GMT+8, 2021-9-27 06:38

Powered by CcTry.CoM

© 2009-2021 cctry.com

快速回复 返回顶部 返回列表