将控制台输出重定向到textbox的dotnet类
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Threading;
{
/// <summary>
/// 重定向的类
/// </summary>
public class Redirect : IDisposable
{
/// <summary>
/// 重定向类的代码
/// </summary>
public enum RdEventType
{
//错误事件
ErrorEvent,
//输出事件
DataEvent,
//stop事件
StopEvent
}
/// 事件参数
/// </summary>
public struct RdEventArgs
{
//code
public RdEventType eventtype;
//字符串(错误时代表错误信息,数据时代表数据字符串,stop时代表停止信息)
public string info;
};
/// 错误处理事件类型
/// </summary>
/// <param name="code"></param>
public delegate void RdEvent(RdEventArgs args);
/// 构造函数1
/// </summary>
/// <param name="szCommand">命令行</param>
/// <param name="szCurrentDirectory">当前目录</param>
public Redirect(string szCommand, string szCurrentDirectory)
{
m_szCommand = szCommand;
m_szCurrentDirectory = szCurrentDirectory;
m_running = false;
//默认100毫秒
m_dwMilliseconds = 100;
m_processInfo = new PROCESS_INFORMATION();
m_PipeData = new byte[BUF_SIZE];
m_readtimer = new System.Windows.Forms.Timer();
m_readtimer.Enabled = false;
m_readtimer.Interval = (int)m_dwMilliseconds;
m_readtimer.Tick += new EventHandler(timertick);
}
/// 构造函数2
/// </summary>
/// <param name="szCommand"></param>
public Redirect(string szCommand)
:this(szCommand,null)
{
}
/// 构造函数3
/// </summary>
public Redirect()
:this(null,null)
{
}
class PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
class SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
class STARTUPINFO
{
public int cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public int dwX;
public int dwY;
public int dwXSize;
public int dwYSize;
public int dwXCountChars;
public int dwYCountChars;
public int dwFillAttribute;
public int dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, SECURITY_ATTRIBUTES lpProcessAttributes,
SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, int dwCreationFlags, IntPtr lpEnvironment,
string lpCurrentDirectory, STARTUPINFO lpStartupInfo, PROCESS_INFORMATION lpProcessInformation);
static extern bool CreatePipe(out IntPtr hReadPipe, out IntPtr hWritePipe,
SECURITY_ATTRIBUTES lpPipeAttributes, uint nSize);
static extern bool PeekNamedPipe(IntPtr handle, byte[] buffer, uint nBufferSize, ref uint bytesRead,
ref uint bytesAvail, ref uint BytesLeftThisMessage);
static extern bool ReadFile(IntPtr hFile, byte[] lpBuffer,
uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped);
static extern Int32 WaitForSingleObject(IntPtr handle, Int32 milliseconds);
static extern bool CloseHandle(IntPtr hObject);
static extern bool TerminateProcess(IntPtr hProcess, uint uExitCode);
const int STARTF_USESTDHANDLES = 0x00000100;
const short SW_HIDE = 0;
const int WAIT_OBJECT_0 = 0;
/// 错误报告事件
/// </summary>
public event RdEvent RdEventHandler;
private IntPtr m_PipeWriteHandle;
private PROCESS_INFORMATION m_processInfo;
byte[] m_PipeData;
/// <summary>
/// buffer的大小
/// </summary>
private const int BUF_SIZE = 8192;
/// 启动
/// </summary>
public void Run()
{
//如果已经运行
if (m_running) return;
STARTUPINFO StartupInfo=new STARTUPINFO();
bool Success;
SecurityAttributes.nLength = Marshal.SizeOf(SecurityAttributes);
SecurityAttributes.bInheritHandle = 1;
SecurityAttributes.lpSecurityDescriptor =IntPtr.Zero;
Success = CreatePipe(out m_PipeReadHandle, out m_PipeWriteHandle, SecurityAttributes, 0);
if (!Success)
{
RaiseRdEvent(RdEventType.ErrorEvent, "CreatePipe failed.");
return;
}
StartupInfo.cb = Marshal.SizeOf(StartupInfo);
StartupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
StartupInfo.wShowWindow = SW_HIDE;
StartupInfo.hStdOutput = m_PipeWriteHandle;
StartupInfo.hStdError = m_PipeWriteHandle;
Success = CreateProcess(null, m_szCommand, null, null, true, 0, IntPtr.Zero,
m_szCurrentDirectory, StartupInfo, m_processInfo);
if (!Success)
{
RaiseRdEvent(RdEventType.ErrorEvent, "CreateProcess failed.");
return;
}
//成功,启动时钟周期性的读取管道
m_running = true;
m_readtimer.Start();
}
private void RaiseRdEvent(RdEventType eventtype,string info)
{
RdEventArgs args = new RdEventArgs();
args.eventtype = eventtype;
args.info = info;
if (RdEventHandler != null)
RdEventHandler(args);
}
/// 时钟触发
/// </summary>
/// <param name="state"></param>
private void timertick(object sender, EventArgs e)
{
uint NumBytesRead = 0;
uint TotalBytesAvailable = 0;
uint BytesLeftThisMessage = 0;
//查看数据
bool Success = PeekNamedPipe(m_PipeReadHandle,m_PipeData,1,ref NumBytesRead,
ref TotalBytesAvailable,ref BytesLeftThisMessage);
if(!Success)
{
RaiseRdEvent(RdEventType.ErrorEvent, "PeekNamedPipe failed.");
return;
}
//如果读到数据
if(NumBytesRead>0)
{
Success = ReadFile(m_PipeReadHandle,m_PipeData,BUF_SIZE,out NumBytesRead,IntPtr.Zero);
if(!Success)
{
RaiseRdEvent(RdEventType.ErrorEvent,"ReadFileError failed.");
return;
}
//处理得到的数据
dealReadData(m_PipeData, NumBytesRead);
return;
}
//如果没有读到数据,查看进程是否结束了
if(WaitForSingleObject(m_processInfo.hProcess,0)==WAIT_OBJECT_0)//结束了
{
m_running = false;
RaiseRdEvent(RdEventType.StopEvent, "terminated normal.");
m_readtimer.Stop();
FreeHandle();
}
//没有结束,do nothing
}
/// 处理得到的数据
/// </summary>
/// <param name="data"></param>
/// <param name="num"></param>
private void dealReadData(byte[] data,uint num)
{
Array.Resize(ref data, (int)num);
//转换为string byte[]中是dbcs,控制台输出的为dbcs字符
Encoding ec = Encoding.Default;//使用当前系统默认的ansi代码页
string str = ec.GetString(data);
//替换'\b' backspace 为空格
str.Replace('\b', ' ');
//产生事件
RaiseRdEvent(RdEventType.DataEvent, str);
}
/// 停止
/// </summary>
public void Stop()
{
if (!m_running) return;
//置标志
m_running = false;
m_readtimer.Stop();
//结束进程
TerminateProcess(m_processInfo.hProcess, 0);
RaiseRdEvent(RdEventType.StopEvent, "terminated by user.");
//释放
FreeHandle();
}
private void FreeHandle()
{
CloseHandle(m_processInfo.hThread);
m_processInfo.hThread = IntPtr.Zero;
CloseHandle(m_processInfo.hProcess);
m_processInfo.hProcess = IntPtr.Zero;
CloseHandle(m_PipeReadHandle);
m_PipeReadHandle = IntPtr.Zero;
CloseHandle(m_PipeWriteHandle);
m_PipeWriteHandle = IntPtr.Zero;
}
/// 命令行
/// </summary>
private string m_szCommand;
/// 当前目录
/// </summary>
private string m_szCurrentDirectory;
/// 是否工作中
/// </summary>
private bool m_running;
/// 是否工作中
/// </summary>
public bool Running
{
get { return m_running; }
}
/// command属性
/// </summary>
public string Command
{
set
{
if (m_running) return;
m_szCommand = value;
}
get { return m_szCommand; }
}
/// 当前目录
/// </summary>
public string CurrentDirectory
{
set
{
if (m_running) return;
m_szCurrentDirectory = value;
}
get { return m_szCurrentDirectory; }
}
/// 读取管道数据的毫秒数
/// </summary>
private uint m_dwMilliseconds;
/// <summary>
/// 读取时钟,使用windows时钟,避免事件产生在线程中
/// </summary>
private System.Windows.Forms.Timer m_readtimer;
/// 读取管道数据的毫秒数
/// </summary>
public uint ReadMilliseconds
{
set
{
if (m_running) return;
m_dwMilliseconds = value;
}
get { return m_dwMilliseconds; }
}
public bool IsDisposed
{
get { return disposed; }
}
/// 重载dispose,释放非托管资源
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
//do something
if (!IsDisposed)
{
if (disposing){/*free managed resource*/}
//free unmanaged resource
Stop();
m_readtimer.Dispose();
}
disposed = true;
}
{
Dispose(true);
GC.SuppressFinalize(this);
}
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
// Do not provide destructors in types derived from this class.
~Redirect()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
#endregion
}
}
转载于:https://blog.51cto.com/happyoldbear/58552
将控制台输出重定向到textbox的dotnet类相关推荐
- 【Java文件操作(八)】将控制台输出重定向到txt文件
我的博客--Java文件操作系列 [Java文件操作(一)]递归打印文件目录 [Java文件操作(二)]删除文件夹,但保留其内部文件 [Java文件操作(三)]递归复制文件夹内所有文件 [Java文件 ...
- java如何在控制台重定向_R - 控制台输出重定向不能(可靠地)从函数调用中工作...
我编写了以下代码来将控制台输出重定向到文本文件 . 当我以交互方式运行代码时,所有三个命令'(dim,str,summary)输出都会出现在文本文件中 . 但是,当我将代码放在函数中并以交互方式运行函 ...
- C# 在自定义的控制台输出重定向类中整合调用方信息
C# 在自定义的控制台输出重定向类中整合调用方信息 目录 C# 在自定义的控制台输出重定向类中整合调用方信息 一.前言 二.输出重定向基础版 三.输出重定向进阶版(传递调用方信息) 四.后记及资源 独 ...
- python控制台输出到文件_Python print 立即打印内容到重定向的文件
看到本文标题也许要奇怪了,Python 的 print 难道不是也上可以看到结果的吗?在 Python shell 下只要 >> print('Hello world!') Hello w ...
- ASP.NET Core 解决控制台输出日志内容前面[40m等乱码字符
在默认我写了一个 WPF 程序去做管理 ASP.NET Core 进程的日志的时候,重定向输出的内容里面每一行前面都添加了很多乱码字符串.其实这是 ASP.NET Core 控制台的颜色字符,解决方法 ...
- python将控制台输出保存至文件
很多时候在Linux系统下运行python程序时,控制台会输出一些有用的信息.为了方便保存这些信息,有时需要对这些信息进行保存.这里介绍几种将控制台输出保存到文件中的方式: 1 重定向标准输出流 重定 ...
- python文件输出-python将控制台输出保存至文件的方法
很多时候在Linux系统下运行python程序时,控制台会输出一些有用的信息.为了方便保存这些信息,有时需要对这些信息进行保存.这里介绍几种将控制台输出保存到文件中的方式: 1 重定向标准输出流 重定 ...
- java生成html 控制编码方式_JAVA中文字符编码问题详解 控制台输出
JAVA的中文字符乱码问题一直很让人头疼.特别是在WEB应用中.网上的分析文章和解决方案都很多,但总是针对某些特定情况的.很多次遇到乱码问题后, 经过极为辛苦的调试和搜索资料后终于解决,满以为自己已经 ...
- linux 输入、输出重定向的概念和用法详解(Day01)
介绍重定向之前先来介绍几个重要的概念:(笔记不易---- 转载请注明出处) 1.linux 的标准输入与输出 linux标准输入设备指的是键盘,标准输出设备指的是显示器,标准错误输出指的是显示器. ...
最新文章
- 【基础】-设置VS2015开发环境
- 蓝桥杯2015初赛试题
- gitlab linux版本下载,Linux安装GitLab版本控制软件
- 智力测试题2——“五个人、五座房子”问题
- listActivity和ExpandableListActivity的简单用法
- Android之popWindows底部弹出挡住了华为虚拟键盘问题
- 2015蓝桥杯省赛---java---A---2(星系炸弹)
- 传一个实体一个string_没想到,一个小小的String还有这么多窍门
- anaconda cuda路径_anaconda+cuda+cudann+tensorflow环境安装
- 埋石图根点lisp代码_GPS测量作业流程.doc
- 如果您能天天读上一遍,就能和老外对话了!
- JDK1.8后List转Map
- java编程比赛_[阶段一]java基础编程比赛
- 【windows环境 PKCS11库Demo 用于劫持PKCS11库并打印参数】
- 微信小程序全方位深度解析课程Dome-First项目module
- python读取文本某一行内容
- 桌面文档另存计算机怎么存,如何把word保存到桌面
- 三七互娱后端工程师笔试记录
- Why So Serious
- 如何在visual studio下编译zxing cpp,以及zxing c++的使用
热门文章
- AMESim软件建模
- java 判断是否包含中文_Java 判断字符串是否包含中文正则表达式
- c多线程并发处理方式_Java并发基础,不怕你看不懂
- enable pen pressure in ps
- Farthest Point Sampling on 2d image
- 3.7.4 - Indexing and Slicing Strings
- 自注意力机制卷积神经网络的作物叶片病害识别
- 编写Java程序,在屏幕上显示带标题的窗口,并添加一个按钮。当用户单击按钮时,结束程序。
- java map扩容机制_java中ConcurrentHashMap的扩容机制问题
- mysql双活存储容量 TB_Mysql双活方案 - osc_fted3syf的个人空间 - OSCHINA - 中文开源技术交流社区...