功能大概描述一下如果直接StandardOutput.ReadToEnd()这种方法,有很多限制

这类方式必须把命令全部执行一次写入并标记为exit,而且返回内容的获取会一直等待,如果在主线程里使用会导致假死。

若遇到执行时间长,同时会在执行中输出进度的命令,则明显不适应

对于部分特殊字符这类方法会直接中断一直等待(特别是对包含asc颜色等样式的输出)

本文的工具类解决以上问题,使用委托订阅的方式即时的输出执行过程,不用等待,异步输出结算后自动退出

方便应对类似这种需要长时间运行即时输出的打包命令。

下面直接贴出代码,方便后面的朋友 直接使用。

前一个类StreamAsynRead是用于读取cmd进程返回流IO 后面的MyWindowsCmd为cmd主要功能

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; using System.IO;
using System.Threading; /*******************************************************************************
* Copyright (c) 2016 lulianqi
* All rights reserved.
*
* 文件名称:
* 内容摘要: mycllq@hotmail.com
*
* 历史记录:
* 日 期: 201601212 创建人: lulianqi mycllq@hotmail.com
* 描 述: 创建
*******************************************************************************/ namespace yourNamespaceName
{
class StreamAsynRead:IDisposable
{
public delegate void delegateGetStreamAsynReadEventHandler(object sender, string outData);
public event delegateGetStreamAsynReadEventHandler OnGetAsynReadData; private Stream baseStream;
private Thread readStreamThread;
private Encoding baseEncode;
private bool isDropAscStyle;
private bool willKill; /// <summary>
/// 异步读取指定IO流并即时返回直到该流结束(初始化完成后即开始读取)
/// </summary>
/// <param name="yourBaseStream">目标IO流</param>
/// <param name="yourEncode">编码方式</param>
/// <param name="dropAscStyle">是否丢弃ASC样式</param>
/// <param name="yourGetAsynReadData">数据返回委托</param>
public StreamAsynRead(Stream yourBaseStream, Encoding yourEncode, bool dropAscStyle , delegateGetStreamAsynReadEventHandler yourGetAsynReadData)
{
if (yourBaseStream == null)
{
throw new Exception("yourBaseStream is null");
}
else
{
isDropAscStyle = dropAscStyle;
baseStream = yourBaseStream;
baseEncode = yourEncode;
OnGetAsynReadData += yourGetAsynReadData;
StartRead();
willKill = false;
}
} public StreamAsynRead(Stream yourBaseStream, Encoding yourEncode, delegateGetStreamAsynReadEventHandler yourGetAsynReadData)
: this(yourBaseStream, yourEncode, false, yourGetAsynReadData){} public StreamAsynRead(Stream yourBaseStream, delegateGetStreamAsynReadEventHandler yourGetAsynReadData)
: this(yourBaseStream, ASCIIEncoding.UTF8, false, yourGetAsynReadData) { } public bool IsdropAscStyle
{
get { return isDropAscStyle; }
set { isDropAscStyle = value; }
} private void PutOutData(string yourData)
{
if(OnGetAsynReadData!=null)
{
this.OnGetAsynReadData(this, yourData);
}
} private bool StartRead()
{
if(baseStream==null)
{
return false;
}
if(readStreamThread!=null)
{
if (readStreamThread.IsAlive)
{
readStreamThread.Abort();
}
}
readStreamThread = new Thread(new ParameterizedThreadStart(GetDataThread));
readStreamThread.IsBackground = true;
readStreamThread.Start(baseStream);
return true;
} private void GetDataThread(object ReceiveStream)
{
/*
try
{
}
catch (ThreadAbortException abortException)
{
Console.WriteLine((string)abortException.ExceptionState);
}
* */ Byte[] read = new Byte[];
Stream receiveStream = (Stream)ReceiveStream;
int bytes = receiveStream.Read(read, , );
string esc = baseEncode.GetString(new byte[] { , });
//string bs = baseEncode.GetString(new byte[] { 8 }); // \b
string re = "";
while (bytes > && !willKill)
{
re = baseEncode.GetString(read, , bytes);
if (isDropAscStyle)
{
while (re.Contains(esc))
{
int starEsc = re.IndexOf(esc);
int endEsc = re.IndexOf('m', starEsc);
if (endEsc > )
{
re = re.Remove(starEsc, (endEsc - starEsc + ));
}
else
{
re = re.Remove(starEsc, );
}
}
}
PutOutData(re);
bytes = receiveStream.Read(read, , );
}
} public void Dispose()
{
willKill = true;
}
} class MyWindowsCmd : IDisposable
{
public enum RedirectOutputType
{
RedirectStandardInput,
RedirectStandardError
} public delegate void delegateGetCmdMessageEventHandler(object sender, string InfoMessage, RedirectOutputType redirectOutputType);
/// <summary>
/// 订阅CMD返回数据
/// </summary>
public event delegateGetCmdMessageEventHandler OnGetCmdMessage; private System.Diagnostics.Process p = new System.Diagnostics.Process();
StreamAsynRead standardOutputRead = null;
StreamAsynRead standardErrorRead = null;
private string errorMes = null;
private string cmdName = null;
private bool isStart = false;
private bool isDropAscStyle = false; public MyWindowsCmd()
{
p.StartInfo.FileName = "cmd.exe";
cmdName = "CMD";
p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动
p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
p.StartInfo.CreateNoWindow = true;//不显示程序窗口
p.StartInfo.ErrorDialog = true;
} /// <summary>
/// 含名称字段的构造函数
/// </summary>
/// <param name="yourNmae">CMD名称(方便区分多份CMD实例)</param>
public MyWindowsCmd(string yourNmae):this()
{
cmdName = yourNmae;
} private void ShowMessage(string mes, RedirectOutputType redirectOutputType)
{
if (OnGetCmdMessage != null)
{
this.OnGetCmdMessage(this, mes, redirectOutputType);
}
} /// <summary>
/// 获取CMD名称
/// </summary>
public string CmdName
{
get { return cmdName; }
} /// <summary>
/// 获取最近的错误
/// </summary>
public string ErrorMes
{
get { return errorMes; }
} /// <summary>
/// 获取一个值,盖值指示该CMD是否启动
/// </summary>
public bool IsStart
{
get { return isStart; }
} /// <summary>
/// 获取或设置获取内容回调时是否丢弃ASK颜色等样式方案(如果您的应用不具备处理这种样式的功能,请选择放弃该样式)
/// </summary>
public bool IsDropAscStyle
{
get { return isDropAscStyle; }
set { isDropAscStyle = value; }
} /// <summary>
/// 启动CMD
/// </summary>
/// <returns>是否成功启动</returns>
public bool StartCmd()
{
if(isStart)
{
errorMes = "[StartCmd]" + "is Already Started";
return false;
}
try
{
p.Start();//启动程序
//System.Text.Encoding.GetEncoding("gb1232");
if (standardOutputRead!=null)
{
standardOutputRead.Dispose();
}
if (standardErrorRead!=null)
{
standardErrorRead.Dispose();
}
standardOutputRead = new StreamAsynRead(p.StandardOutput.BaseStream, System.Text.Encoding.Default, true, new StreamAsynRead.delegateGetStreamAsynReadEventHandler((obj, str) => { this.OnGetCmdMessage(this, str, RedirectOutputType.RedirectStandardInput); }));
standardErrorRead = new StreamAsynRead(p.StandardError.BaseStream, System.Text.Encoding.Default, true, new StreamAsynRead.delegateGetStreamAsynReadEventHandler((obj, str) => { this.OnGetCmdMessage(this, str, RedirectOutputType.RedirectStandardError); }));
isStart = true;
return true;
}
catch (Exception ex)
{
errorMes = "[StartCmd]" + ex.Message;
return false;
}
} /// <summary>
/// 执行CMD命令
/// </summary>
/// <param name="yourCmd">cmd命令内容</param>
/// <returns>是否成功</returns>
public bool RunCmd(string yourCmd)
{
if(yourCmd==null || !isStart)
{
return false;
}
try
{
p.StandardInput.WriteLine(yourCmd);
return true;
}
catch(Exception ex)
{
errorMes = "[RunCmd]" + ex.Message;
return false;
}
} /// <summary>
/// 等待执行完成(同步方法,请勿在主线程中调用)
/// </summary>
public void WaitForExit()
{
if (RunCmd("exit"))
{
p.WaitForExit();
}
} /// <summary>
/// 停止该CMD,如果不准备再次启动,请直接调用Dispose
/// </summary>
public void StopCmd()
{
if(isStart)
{
p.Close();
isStart = false;
}
} public void Dispose()
{
StopCmd();
standardOutputRead.Dispose();
standardErrorRead.Dispose();
}
}
}

因为主要也是为了满足自己的需要,肯定还有很多错误或不合理的地方。

发现任何错误或任何问题及建议,也感谢在下面留言

调用CMD命令的一个.NET工具类(MyWindowsCmd)的更多相关文章

  1. Java调用cmd命令 打开一个站点

    使用Java程序打开一个站点 近期做了个东西使用SWT技术在一个client程序 须要升级时在提示升级 点击窗口上的一个连接 打开下载网页 花费了我非常长时间 用到了把它记录下来  怕是忘记,须要时能 ...

  2. PHP 命令行参数解析工具类

    <?php/** * 命令行参数解析工具类 * @author guolinchao * @email luoyecb@163.com */class CommandLine{ // store ...

  3. java调用kettle的job和transfer工具类

    package com.woaiyitiaocai.util; import java.util.Map; import java.util.UUID; import org.apache.log4j ...

  4. 分享一个Snackbar工具类 SnackbarUtils;

    分享一个Snackbar工具类,源代码也是在Github上面找的,自己做了一下修改: 功能如下: 1:设置Snackbar显示时间长短                 1.1:Snackbar.LEN ...

  5. 使用node自动生成html并调用cmd命令提交代码到仓库

    生成html提交到git仓库 基于目前的express博客,写了一点代码,通过request模块来请求站点,将html保存到coding-pages目录,复制静态文件夹到coding-pages,最后 ...

  6. python调用cmd显示中文乱码及调用cmd命令

    os.system('dir') 解决方法加上 os.system('chcp 65001') ____________________________________________________ ...

  7. java中定义一个CloneUtil 工具类

    其实所有的java对象都可以具备克隆能力,只是因为在基础类Object中被设定成了一个保留方法(protected),要想真正拥有克隆的能力, 就需要实现Cloneable接口,重写clone方法.通 ...

  8. C语言调用Cmd命令以及执行系统软件

    C语言调用Cmd命令以及执行系统软件 http://blog.csdn.net/qq_16814591/article/details/43676377

  9. IE浏览器中使用js调用cmd命令行demo

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...

随机推荐

  1. ssh密钥登录

    一.生成密钥对(两种方式)并配置 方式1:使用ssh-keygen(1)生成并配置 (1)生成密钥对 [root@iZwz9catu2mrq92b07d1d0Z ~]# ssh-keygen -t r ...

  2. Less的条件表达式

    Less的条件表达式 当需要根据表达式,而不是参数的值或数量进行匹配时,条件表达式(Guards)就显得非常有用.如果你熟悉函数式编程的话,对条件表达式也不会陌生. 为了尽可能地接近CSS的语言结构, ...

  3. js 事件冒泡和事件捕获

    事件流:指的是网页中元素接受事件的顺序,它是一个概念,而不是具体的实际的东西 事件冒泡:指的是内层元素的事件,会触发包含着此元素的外层元素的事件,触发的顺序是:由内而外的 例如: <!DOCTY ...

  4. Thinkphp导入外部类的方法

    相信很多人在使用TP时候都苦恼使用外部类各种不成功 下面为大家详细介绍下引用方法和注意细节 手动加载第三方类库 由于第三发类库没有具体的命名空间,所以需要使用以下几种方法手动导入 1.import方法 ...

  5. 读取不标准的JSON数据

    正常的JSON数据 [      {"key":"UI","value":"UII"},      {"key ...

  6. RBAC(Role-Based Access Control,基于角色的权限访问控制)—权限管理设计

    RBAC模型的核心是在用户和权限之间引入了角色的概念,将用户和权限进行解耦,采用用户确定角色,角色分配权限,进而间接达到给用户分配角色的目的 这样采用的方式优点在于 (1)降低管理成本--由于一个角色 ...

  7. Haproxy配置日志显示

    安装完haproxy后,日志默认是记录在系统日志下的.为了便于排错以及查看日志,我们需要将haproxy日志剥离出来. 在配置前,我们先来了解下日志的level: local0-local7 16-2 ...

  8. Solr中Field常用属性

    FieldType 实例:<fieldType name="text_ik" class="solr.TextField"></fieldTy ...

  9. js 匹配2个字符串相似度

    strSimilarity2Number: function (s, t) { var n = s.length, m = t.length, d = []; var i, j, s_i, t_j, ...

  10. Backtrack无线攻防(很任性的一篇)

    首先你得有一个backtrack操作系统 然后还得花钱买一个无线网卡,最好是Intel的,还有要是USB接口的,可能是因为其他接口我不会接.