怎么获得控制台程序输出
来源:互联网 发布:水果销售软件 编辑:程序博客网 时间:2024/06/10 18:28
假设我在GUI程序中执行ping 命令,怎么把ping命令产生的控制台输出 在GUI程序中获得.
我现在是用ShellExecute执行的ping命令
HINSTANCE hInstance = ShellExecute(NULL,NULL,"ping.exe","10.57.18.166",NULL,SW_SHOW);
怎么获得输出?
如果这种方法不行,那用哪种方法可以获得输出?
我不想用>a.txt管道形式先输出到文件,然后再读取,我想直接获得,谢谢
---------------------------------------------------------------
用管道重定义标准输出. 用 CreateProcess 可以指定控制台程序的输出流
---------------------------------------------------------------
输出管道重定向
---------------------------------------------------------------
在Windows环境下的所谓shell程序就是dos命令行程序,比如VC的CL.exe命令行编译器,JDK的javac编译器,启动java程序用的java.exe都是标准的shell程序。截获一个shell程序的输出是很有用的,比如说您可以自己编写一个IDE(集成开发环境),当用户发出编译指令时候,你可以在后台启动shell 调用编译器并截获它们的输出,对这些输出信息进行分析后在更为友好的用户界面上显示出来。为了方便起见,我们用VB作为本文的演示语言。
通常,系统启动Shell程序时缺省给定了3个I/O信道,标准输入(stdin), 标准输出stdout, 标准错误输出stderr。之所以这么区分是因为在早期的计算机系统如PDP-11的一些限制。那时没有GUI, 将输出分为stdout,stderr可以避免程序的调试信息和正常输出的信息混杂在一起。
通常, shell程序把它们的输出写入标准输出管道(stdout)、把出错信息写入标准错误管道(stderr)。缺省情况下,系统将管道的输出直接送到屏幕,这样一来我们就能看到应用程序运行结果了。
为了捕获一个标准控制台应用程序的输出,我们必须把standOutput和standError管道输出重定向到我们自定义的管道。
下面的代码可以启动一个shell程序,并将其输出截获。
'执行并返回一个命令行程序(shell程序)的标准输出和标准错误输出
'通常命令行程序的所有输出都直接送到屏幕上
Private Function ExecuteApp(sCmdline As String) As String
Dim proc As PROCESS_INFORMATION, ret As Long
Dim start As STARTUPINFO
Dim sa As SECURITY_ATTRIBUTES
Dim hReadPipe As Long '负责读取的管道
Dim hWritePipe As Long '负责Shell程序的标准输出和标准错误输出的管道
Dim sOutput As String '放返回的数据
Dim lngBytesRead As Long, sBuffer As String * 256
sa.nLength = Len(sa)
sa.bInheritHandle = True
ret = CreatePipe(hReadPipe, hWritePipe, sa, 0)
If ret = 0 Then
MsgBox "CreatePipe failed. Error: " & Err.LastDllError
Exit Function
End If
start.cb = Len(start)
start.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
' 把标准输出和标准错误输出重定向到同一个管道中去。
start.hStdOutput = hWritePipe
start.hStdError = hWritePipe
start.wShowWindow = SW_HIDE '隐含shell程序窗口
' 启动shell程序, sCmdLine指明执行的路径
ret = CreateProcessA(0&, sCmdline, sa, sa, True, NORMAL_PRIORITY_CLASS, _
0&, 0&, start, proc)
If ret = 0 Then
MsgBox "无法建立新进程,错误码:" & Err.LastDllError
Exit Function
End If
' 本例中不必向shell程序送信息,因此可以先关闭hWritePipe
CloseHandle hWritePipe
' 循环读取shell程序的输出,每次读取256个字节。
Do
ret = ReadFile(hReadPipe, sBuffer, 256, lngBytesRead, 0&)
sOutput = sOutput & Left$(sBuffer, lngBytesRead)
Loop While ret <> 0 ' 如果ret=0代表没有更多的信息需要读取了
' 释放相关资源
CloseHandle proc.hProcess
CloseHandle proc.hThread
CloseHandle hReadPipe
ExecuteApp = sOutput ' 输出结果
End Function
我对这个程序进行一些解释。
ret = CreatePipe(hReadPipe, hWritePipe, sa, 0)
大家可以看到,首先我们建立一个匿名管道。该匿名管道稍候将用来取得与被截获的应用程序的联系。其中hReadPipe用来获取shell程序的输出,而hWritePipe可以用来向应用程序发送信息。如同现实世界中的水管一样,水从管道的一端流进从另一端流出。您把水想象为信息,水管就是匿名管道,这样一来就很好理解这段程序了。
然后就是设置shell应用程序的初始属性。 Dwflags可以指示系统在创建新进程时新进程使用了自定义的wShowWindow, hStdInput,hStdOutput和hStdError。(windows显示属性,标准输入,标准输出,标准错误输出。)
再把shell应用程序的标准输出和标准错误输出都定向到我们预先建好的管道中。
代码如下:
start.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
start.hStdOutput = hWritePipe
start.hStdError = hWritePipe
好,现在可以调用建立新进程的函数了:
ret = CreateProcessA(0&, sCmdline, sa, sa, True, NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)
然后,循环读管道里的数据直到无数据可读为止。
Do
ret = ReadFile(hReadPipe, sBuffer, 256, lngBytesRead, 0&) '每次读256字节
sOutput = sOutput & Left$(sBuffer, lngBytesRead) '送入一个字符串中
Loop While ret <> 0 '若 ret = 0 表明没有数据等待读取。
然后,释放不用的资源。
用法很简单:比如:
MsgBox ExecuteApp("c:/windows/command/mem.exe)
是很方便吧?
不过,这些程序是在NT下的,如果要在95下实现还需要一点点改动。因为如果该函数调用一个纯win32的程序,没问题。可是95是16,win32混合的系统,当你试图调用一个16位的DOS应用程序那么,那么这个办法会导致相关进程挂起。因为这涉及到WindowsNT和Windows 95对shell的不同实现。
在win95中,16位shell程序关闭时并不保证重定向的管道也关闭,这样,当你的程序试图读取一个已经关闭的shell程序的重定向管道时,你的程序就挂了。
那么,有解决办法吗?回答是肯定的。
解决办法就是用一个win32的应用程序作为您的应用程序和shell程序的中间人。中间人程序继承并重定向了主程序的输入输出,然后中间人程序启动指定的shell程序。该shell程序也就继承并重定向了主
- 怎么获得控制台程序输出
- 调用控制台应用程序并获得程序的输出信息
- 执行控制台程序并且获得它的输出结果
- 怎么隐藏控制台程序的控制台窗口
- VS非控制台程序输出到控制台
- c++控制台程序怎么隐藏
- c++控制台程序怎么隐藏
- form程序利用控制台输出
- 用控制台程序输出九九乘法表
- MFC程序显示控制台输出
- Qt输出到控制台/接收程序输出
- MFC程序中获得控制台的输入
- 获得电脑的信息 控制台程序
- 怎么用VS2008做一个控制台程序
- VS2010控制台程序调试结果怎么一闪而过
- 怎么解决VS运行程序控制台一闪而过
- 怎么用VC6.0建立控制台程序
- 调用控制台程序,并实施获取控制台输出文字
- 用刷新网页的办法更新user control控件内容
- VclSkin 简要说明和使用教程
- Notes from Jing
- 用vc下载和获取远程文件大小
- 精通javascript (一)
- 怎么获得控制台程序输出
- 用什么方法调用控制台程序,同时做到:1.隐藏控制台窗口;2.获取控制台程序的exit status
- 快速打开管理工具(开始 -->运行)
- MFC应用程序使用控制台的方法
- Silverlight实例教程 - Out of Browser开篇
- wincapp
- 【其它】【RQNOJ】哥德巴赫猜想(Easy)
- 如果想念一个人,就响两下他/她的手机。
- 学会高傲的活着