打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Createprocess控制台程序输出重定向
分类: 2.1 VC++/MFC 2010-04-11 11:58 5729人阅读 评论(0) 收藏 举报

      在Windows编程中,并非每一个应用程序都需要一个图形用户界面(GUI),很多情况下,我们可以编写一个控制台应用程序,这样程序更小,加载更快,传输时间也短,同时也丝毫不牺牲程序应有的功能。这种程序特别适合那些在后台运行的程序,比如压缩、杀毒、上传下载等等。如果我们的确需要在GUI执行这些程序,以完成某些比如类似于磁盘格式化的功能,我们可以在GUI程序中创建一个新的进程,调用这些已有的控制台应用程序,帮助完成这些功能。然而令人失望的是,我们每次加载这些控制台应用程序时,图形程序总会在加载的过程中产生一个不受欢迎的控制台窗口,从而使我们图形用户界面显得不伦不类,当用户看到这个界面时,尤其看到我们加载的是别人编写的或者是操作系统提供的控制台应用程序,就会对我们产品的可信度表示怀疑,甚至大打折扣。因此我们必须竭力屏蔽这个窗口不让它显示出来,同时我们还需要把程序运行的结果定向到一个文本文件中,控制台程序的输入部分工作可以由交给GUI来完成。就像Visual C++编译一个程序一样,由MsDev.exe(GUI程序)负责加载编译器cl.exe(控制台程序)进行后台编译,然后把编译的结果定向到一个文件,并把编译结果输出到前台图形界面的一个窗口中,而用户在编译的过程中根本不会察觉这个过程,C++为应用程序加载提供了多个函数,比如 _spawnlp、ShellExecute、system、_exec等函数,这些函数除了system之外,都无法实现控制台程序的输出定向,而 system函数的缺点是会导致一个控制台窗口出现,如果计算机配置是一个全屏命令提示行模式,它就会把你的GUI程序直接切换到全屏控制台窗口,显然这是一个很不体面的解决方案。

_spawnlp( _P_WAIT,"netstat","-e","-s","-n","r","a","-p","ip",NULL);
::ShellExecute(NULL,NULL,"Ping.exe","168.192.0.1 >1.txt",NULL,SW_SHOWNORMAL);
system("Format a:/q >NULL");
_execlp("expand.exe","Source.cab","-f:m*.dll",c:/winnt/sytem32",NULL );

能够成功实现控制台应用程序输出定向的方法是调用CreateProcess函数。通过这个函数我们可以实现创建一个进程,能够隐藏控制台窗口,并把控制台窗口的输出结果定向输出到一个文本文件。
在Windows 2000环境下,CreateProcess函数提供了一个名叫CREATE_NO_WINDOW的标志,这个标志能够成功阻止控制台窗口出现,然而在 Windows 98环境下,这个标志不被支持。为了实现两种环境下隐藏控制台窗口,我们可以通过设置STARTINFO结构成员并把它传递给CreateProcess 函数来达到这个目的。
下面是程序实现部分的界面和部分代码:

  1. void CDoCmdDlg::OnBnClickedButton1()  
  2. {  
  3.     UpdateData();  
  4.     BYTE b1,b2,b3,b4;  
  5.     if ( m_IPAddressCtrl.GetAddress ( b1,b2,b3,b4 ) <4 )  
  6.     {  
  7.                 //获得IP地址的内容,不能空缺  
  8.         m_IPAddressCtrl.SetFocus ();  
  9.         return;  
  10.     }  
  11.     char cmdLine[MAX_PATH];  
  12.     wsprintf ( cmdLine,"Ping.exe %d.%d.%d.%d",b1,b2,b3,b4 );  
  13.     SECURITY_ATTRIBUTES sa={sizeof ( sa ),NULL,TRUE};  
  14.     SECURITY_ATTRIBUTES *psa=NULL;  
  15.     DWORD dwShareMode=FILE_SHARE_READ|FILE_SHARE_WRITE;  
  16.     OSVERSIONINFO osVersion={0};  
  17.     osVersion.dwOSVersionInfoSize =sizeof ( osVersion );  
  18.     if ( GetVersionEx ( &osVersion ) )  
  19.     {  
  20.         if ( osVersion.dwPlatformId ==VER_PLATFORM_WIN32_NT )  
  21.         {  
  22.             psa=&sa;  
  23.             dwShareMode|=FILE_SHARE_DELETE;  
  24.         }  
  25.     }  
  26.         //根据版本设置共享模式和安全属性  
  27.     HANDLE hConsoleRedirect=CreateFile (  
  28.                                 "c://NetStatus.txt",  
  29.                                 GENERIC_WRITE,  
  30.                                 dwShareMode,  
  31.                                 psa,  
  32.                                 OPEN_ALWAYS,  
  33.                                 FILE_ATTRIBUTE_NORMAL,  
  34.                                 NULL );  
  35.     ASSERT ( hConsoleRedirect!=INVALID_HANDLE_VALUE );  
  36.     STARTUPINFO s={sizeof ( s ) };  
  37.     s.dwFlags =STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;  
  38.         //使用标准柄和显示窗口  
  39.     s.hStdOutput =hConsoleRedirect;//将文件作为标准输出句柄  
  40.     s.wShowWindow =SW_HIDE;//隐藏控制台窗口  
  41.     PROCESS_INFORMATION pi={0};  
  42.     if ( CreateProcess ( NULL,cmdLine,NULL,NULL,TRUE,NULL,NULL,NULL,&s,&pi; ) )  
  43.     {  
  44.         //创建进程,执行Ping程序,测试网络是否连通  
  45.         WaitForSingleObject ( pi.hProcess ,INFINITE );  
  46.         //等待进程执行完毕  
  47.         CloseHandle ( pi.hProcess );  
  48.         CloseHandle ( pi.hThread );  
  49.         //关闭进程和主线程句柄  
  50.     }  
  51.     CloseHandle ( hConsoleRedirect );  
  52.     //关闭控制台定向输出文件句柄  
  53.     CFile myFile ( "c://NetStatus.txt",CFile::modeRead );  
  54.     ASSERT ( myFile.m_hFile!=NULL );  
  55.     char * pszNetStatus=new char[myFile.GetLength () +1];  
  56.     ZeroMemory ( pszNetStatus,myFile.GetLength () +1 );  
  57.     myFile.Read ( pszNetStatus,myFile.GetLength () );  
  58.     myFile.Close ();  
  59.     //打开文件,把它读到一个字符缓冲区  
  60.     DeleteFile ( "c://NetStatus.txt" );  
  61.     //删除临时文件  
  62.     m_EditNetStatus.SetWindowText ( pszNetStatus );  
  63.     //把控制台程序输出信息写到编辑框中  
  64.     delete pszNetStatus;  
  65. }  

以上转载自:http://148332727.blog.51cto.com/500316/112316

这里做补充,m_IPAddressCtrl是CIPAddressCtrl的关联变量,m_EditNetStatus是CEdit的关联变量,其中CEdit要设置为Multiline属性。效果如下:

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
19.VC(custom)
第一个真正的Windows程序(在C语言中程序都是黑屏的称为控制台程序(Console Application)这套教程要讲的是带界面的Windows程序(Windows Application)GU
Win32控制台程序是什么
STARTUPINFO结构体
看到同事写的程序,#pragma comment(linker, "/subsystem:...
WIN32API函数CreateProcess
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服