Createprocess控制台程序输出重定向

在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 函数来达到这个目的。

下面是程序实现部分的界面和部分代码:

void CDoCmdDlg::OnBnClickedButton1()
{
UpdateData();
BYTE b1,b2,b3,b4;
if ( m_IPAddressCtrl.GetAddress ( b1,b2,b3,b4 ) <4 )
{
//获得IP地址的内容,不能空缺
m_IPAddressCtrl.SetFocus ();
return;
}
char cmdLine[MAX_PATH];
wsprintf ( cmdLine,"Ping.exe %d.%d.%d.%d",b1,b2,b3,b4 );
SECURITY_ATTRIBUTES sa={sizeof ( sa ),NULL,TRUE};
SECURITY_ATTRIBUTES *psa=NULL;
DWORD dwShareMode=FILE_SHARE_READ|FILE_SHARE_WRITE;
OSVERSIONINFO osVersion={0};
osVersion.dwOSVersionInfoSize =sizeof ( osVersion );
if ( GetVersionEx ( &osVersion ) )
{
if ( osVersion.dwPlatformId ==VER_PLATFORM_WIN32_NT )
{
psa=&sa;
dwShareMode|=FILE_SHARE_DELETE;
}
}
//根据版本设置共享模式和安全属性
HANDLE hConsoleRedirect=CreateFile (
"c://NetStatus.txt",
GENERIC_WRITE,
dwShareMode,
psa,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL );
ASSERT ( hConsoleRedirect!=INVALID_HANDLE_VALUE );
STARTUPINFO s={sizeof ( s ) };
s.dwFlags =STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
//使用标准柄和显示窗口
s.hStdOutput =hConsoleRedirect;//将文件作为标准输出句柄
s.wShowWindow =SW_HIDE;//隐藏控制台窗口
PROCESS_INFORMATION pi={0};
if ( CreateProcess ( NULL,cmdLine,NULL,NULL,TRUE,NULL,NULL,NULL,&s,π ) )
{
//创建进程,执行Ping程序,测试网络是否连通
WaitForSingleObject ( pi.hProcess ,INFINITE );
//等待进程执行完毕
CloseHandle ( pi.hProcess );
CloseHandle ( pi.hThread );
//关闭进程和主线程句柄
}
CloseHandle ( hConsoleRedirect );
//关闭控制台定向输出文件句柄
CFile myFile ( "c://NetStatus.txt",CFile::modeRead );
ASSERT ( myFile.m_hFile!=NULL );
char * pszNetStatus=new char[myFile.GetLength () +1];
ZeroMemory ( pszNetStatus,myFile.GetLength () +1 );
myFile.Read ( pszNetStatus,myFile.GetLength () );
myFile.Close ();
//打开文件,把它读到一个字符缓冲区
DeleteFile ( "c://NetStatus.txt" );
//删除临时文件
m_EditNetStatus.SetWindowText ( pszNetStatus );
//把控制台程序输出信息写到编辑框中
delete pszNetStatus;
}

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

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

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

原文地址:https://www.cnblogs.com/sjwics/p/10460736.html

时间: 2024-08-28 23:50:15

Createprocess控制台程序输出重定向的相关文章

Visual Studio控制台程序输出窗口一闪而过的解决方法

写个Hello World的程序试一下,发现执行结束后输出窗口会一闪而过,并没有出现Press any key to continue的字样.无论是在Visual Studio 2008.2010还是2012中都有这种情况出现,有些人可能会用下面两种方法中的一种: 在程序代码的最后加上system("pause")或者getchar().其实这是属于dos下的命令. 其实问题是你执行时按的是F5,而正确的应该是Ctrl+F5,这样窗口就会显示 Press any key to cont

转-Visual Studio控制台程序输出窗口一闪而过的解决方法

刚接触 Visual Studio的时候大多数人会写个Hello World的程序试一下,有的人会发现执行结束后输出窗口会一闪而过,并没有出现Press any key to continue的字样.无论是在Visual Studio 2008.2010还是2012中都有这种情况出现,有些人可能会用下面两种方法中的一种: 在程序代码的最后加上system("pause")或者getchar().其实这是属于dos下的命令. 其实问题是你执行时按的是F5,而正确的应该是Ctrl+F5,这

(转)Visual Studio控制台程序输出窗口一闪而过的解决方法

背景:熟悉visiual studio工具的使用 刚接触 Visual Studio的时候大多数人会写个Hello World的程序试一下,有的人会发现执行结束后输出窗口会一闪而过,并没有出现Press any key to continue的字样.无论是在Visual Studio 2008.2010还是2012中都有这种情况出现,有些人可能会用下面两种方法中的一种: 在程序代码的最后加上system("pause")或者getchar().其实这是属于dos下的命令. 其实问题是你

控制台终端输出颜色

在使用putty.secureCRT.XShell等终端仿真器连接linux系统时,ls.vim等工具的输出都含有各种颜色,这些颜色的输出大大地增强了文本的可读性. 一.终端文本颜色输出的一般示例 在bash中,通常我们可以使用echo命令加-e选项输出各种颜色的文本,例如: echo -e "\033[31mRed Text\033[0m"echo -e "\033[32mGreen Text\033[0m"echo -e "\033[33mYellow

重定向子进程控制台程序的输入输出

重定向子进程控制台程序的输入输出 重定向所做的工作都在父进程,但需要子进程遵守下面的规则: 子进程程序在输出代码后,等待输入之前需要调用fflush(stdout)函数,这样把输出的内容放入缓冲区,父进程才能及时的读到输出数据. 不遵守以上规则就没办法实现有效的交互了,cmd.exe是遵守这个规则的典范,大部分控制台程序都不遵守这个规则.今天我试图给Google的V8 Javascript 的Shell搞一个GUI,方便我输入Javascript程序,就遇到了v8_shell不遵守这个的问题.好

java笔记--重定向输出流实现程序输出到日志

重定向输出流实现程序输出到日志 利用System类中的setOut()方法,实现输出流的重定向,把它指向一个文件输出流,从而实现日志功能.即: 程序运行后绘制控制台提示运行结束信息,但是在运行过程中的步骤都保存到了日志文件中. 主要方法setOut(): 重新分配System类的标准输出流. public static void setOut(PrintStream out) out表示新的输出流对象 setErr() 重新分配System类的标准错误输出流. public static voi

.net开发环境的认识,控制台程序的创建,输出,输入,定义变量,变量赋值,值覆盖,值拼接,值打印 两种数据类型,整形类型转换

首先感谢向立凯老师带我走进.net这个很好的软件开发程序.通过两天的学习在这个领域的了解也多了很多,让大家先了解一下c#语言 c#是一种全新且简单.安全.快捷面向对象的程序设计语言.是专门为.net应用开发的语言..net的开发都基于一个统一的开发环境 Visual Studio.net.下面我们来看看怎么在Visual Studio.net.下创建以新的项目: 1.打开 2.新建一个项目 通过执行文件-新建-项目菜单命令,会弹出一个新建项目对话框.在这个对话框中选择开发语言为c#,选择框架版本

2017-2-17 c#基础学习 (控制台程序的创建,输出,输入,定义变量,变量赋值,值覆盖,值拼接,值打印)

1 控制台程序的创建 > 新建项目  ,选择 c#,  框架选择4.0 , 选择控制应用台程序, 选择文件保存位置 修改名字. 2 c#输出与输入 >在main函数中编写代码 >在编写时可以先插入Console.ReadLine();防止程序闪退 > Console.Write("实例语句");//不换行输出 Console.WriteLine("示例语句");//换行输出 Console.ReadLine();//等待用户输入 防止闪退 结

双缓冲解决控制台应用程序输出“闪屏”(C/C++,Windows)

使用 C 语言编写游戏的小伙伴们想必起初都要遇到这样的问题,在不断清屏输出数据的过程中,控制台中的输出内容会不断地闪屏.出现这个问题的原因是程序对数据处理花掉的时间影响到了数据显示,或许你可以使用局部覆盖更新方法(减少更新数据量)来缓解闪屏,但是这种方法并不适用于所有场合,尤其是更新数据本身就非常大的场合. 本文将讲述解决控制台应用程序输出闪屏的终级解决方法——双缓冲. 问题呈现 下面的代码演示了在高速不断清屏输出数据的过程的闪屏问题,特邀您一试: 1 2 3 4 5 6 7 8 9 10 11