博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在C#中实现截获shell程序的输出
阅读量:7198 次
发布时间:2019-06-29

本文共 3930 字,大约阅读时间需要 13 分钟。

在Windows环境下的所谓shell程序就是dos命令行程序,比如VC的CL.exe命令行编译器,JDK的javac编译器,启动java程序用的java.exe都是标准的shell程序。截获一个shell程序的输出是很有用的,比如说您可以自己编写一个IDE(集成开发环境),当用户发出编译指令时候,你可以在后台启动shell 调用编译器并截获它们的输出,对这些输出信息进行分析后在更为友好的用户界面上显示出来。

为了方便起见,我们用C#作为本文的演示语言。

通常,系统启动Shell程序时缺省给定了3个I/O信道,标准输入(stdin), 标准输出stdout, 标准错误输出stderr。之所以这么区分是因为在早期的计算机系统如PDP-11的一些限制。那时没有GUI, 将输出分为stdout,stderr可以避免程序的调试信息和正常输出的信息混杂在一起。shell程序把它们的输出写入标准输出管道(stdout)、把出错信息写入标准错误管道(stderr)。缺省情况下,系统将管道的输出直接送到屏幕,这样一来我们就能看到应用程序运行结果了。

为了捕获一个标准控制台应用程序的输出,我们必须把standOutput和standError管道输出重定向到我们自定义的管道。

下面的代码可以启动一个shell程序,并将其输出截获。

// 实例一:WindowsForm应用程序
// 代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace CommandTest
{
    public partial class FrmRunCommand : Form
    {
        System.IO.StreamWriter sw;  // 定义输出流 sw 作为Shell的标准输入,即命令 
        System.IO.StreamReader sr;  
// 定义输出流 sr 作为Shell的标准输出,即正常结果
        System.IO.StreamReader err; // 定义输出流 err 作为Shell的错误输出,即出错结果
        
System.Diagnostics.Process p = new System.Diagnostics.Process();
        System.Diagnostics.ProcessStartInfo psI = new System.Diagnostics.ProcessStartInfo(System.Environment.GetEnvironmentVariable("ComSpec"));

    public FrmRunCommand()

        {
            InitializeComponent();
        }

    private void btnRun_Click(object sender, EventArgs e)

        {
            
            psI.UseShellExecute =false ; 
            psI.RedirectStandardInput   =   true;
            psI.RedirectStandardOutput   =   true;
            psI.RedirectStandardError   =   true;
            psI.CreateNoWindow   =   true;
            p.StartInfo = psI;

        Cursor = System.Windows.Forms.Cursors.WaitCursor;

        

        p.Start();  

            sw = p.StandardInput;  
            sr = p.StandardOutput;
            err = p.StandardError;

        sw.AutoFlush = true;

        if(coboCommand.Text != "")

            {
                sw.WriteLine(coboCommand.Text);
            }
            else
            {
                sw.WriteLine("echo 未输入命令");
            }
            sw.Close();

        tbResult.Text = "输出结果为:"+sr.ReadToEnd();

            tbResult.Text += "\n错误信息:\n"+err.ReadToEnd();

        Cursor = System.Windows.Forms.Cursors.Default;

        }
    }
}
// 程序运行结果:
// 实例二:Asp.net程序
// 实例二文件一:Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" validateRequest="false" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
">
<html xmlns="
" >
<head runat="server">
    <title>Shell程序运行测试页</title>
</head>
<body>
<form runat="server">
<div>
请输入命令:<asp:TextBox runat="server" Width="375px"></asp:TextBox>
<asp:Button runat="server" Text="执行命令" /><br />
<asp:TextBox runat="server" Height="343px" TextMode="MultiLine" Width="551px"></asp:TextBox>
</div>
</form>
</body>
</html>
// 实例二文件二:Default.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class _Default : System.Web.UI.Page 
{
    System.IO.StreamWriter sw;  // 定义输出流 sw 作为Shell的标准输入,即命令 
    System.IO.StreamReader sr;  // 定义输出流 sr 作为Shell的标准输出,即正常结果
    System.IO.StreamReader err; // 定义输出流 err 作为Shell的错误输出,即出错结果
    System.Diagnostics.Process p = new System.Diagnostics.Process();
    System.Diagnostics.ProcessStartInfo psI = new System.Diagnostics.ProcessStartInfo(System.Environment.GetEnvironmentVariable("ComSpec"));

protected void Page_Load(object sender, EventArgs e)

    {
    }
    protected void btnCommand_Click(object sender, EventArgs e)
    {
        psI.UseShellExecute = false;
        psI.RedirectStandardInput = true;
        psI.RedirectStandardOutput = true;
        psI.RedirectStandardError = true;
        psI.CreateNoWindow = true;
        p.StartInfo = psI;

    p.Start();

        sw = p.StandardInput;
        sr = p.StandardOutput;
        err = p.StandardError;

    sw.AutoFlush = true;

    if (tbCommand.Text != "")

        {
            sw.WriteLine(tbCommand.Text);
        }
        else
        {
            tbResult.Text = "请输入命令";
        }
        sw.Close();

    tbResult.Text = "输出结果为:\n" + sr.ReadToEnd().ToString().Replace("\n\n", "\n");

        tbResult.Text += "\n==========================================";
        tbResult.Text += "\n错误信息:\n" + err.ReadToEnd().ToString();
    }
}
// 运行结果如下:
(以上程序均在 Microsoft Visual Studio 2005 中调试通过)

转载地址:http://udkum.baihongyu.com/

你可能感兴趣的文章
sudo日志文件跟踪
查看>>
游戏开发路线图
查看>>
内存分配方式及常见错误
查看>>
phpcms去掉前台和后台登录验证码
查看>>
批处理:查找指定条件的文件复制到指定的目录中
查看>>
导致失败的8项行为习惯
查看>>
我的友情链接
查看>>
PVS7.6 Write Cache模式 “缓存到RAM并且溢出到硬盘” 环境RAM大小配置建议
查看>>
java 双色球×××小程序
查看>>
Exchange性能调优(下)
查看>>
清理MBR
查看>>
VC++结束进程
查看>>
BGP路径选择次序
查看>>
Shell练习-统计出每个IP的访问量有多少?
查看>>
apache的扩展模块安装
查看>>
CentOS7 64位小型操作系统的前期准备(XShell、网络、YUM源、EPEL源)
查看>>
Css3之基础-11 Css定位(定位概念 、定位方式)
查看>>
Java线程中yield与join方法的区别
查看>>
弱电基础知识
查看>>
zabbix监控mysql
查看>>