在.NET程序中使用PIPE(管道技术)
电子科技大学 夏桅 原作
这几天不知道做什么, 受朋友影响, 看完了"新天龙八部", 深受感动, 所以打算做点好事. =) 关于PIPE的应用, 其实原理很简单, 所以我写这文章, 可能要被同行们贻笑大方了, 不过希望对不了解PIPE的新手有点帮助吧.
.NET框架被设计为禁止内存共享的, 但是好在FCL依然提供了一些类, 使得我们还是可以使用管道技术. PIPE, 管道, 他的原理其实就是应用程序的输入输出重定向. 比如原来需要显示在屏幕上的东西不让他传送到屏幕, 而是让你的程序处理/分析, 再显示出结果. 下面是我刚才写的利用cmd.exe执行ping操作, 把结果在一个WinForm的RichTextBox中显示出的例子. [截图]

[代码] using System; using System.Diagnostics; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Threading; using System.Windows.Forms;
namespace Sunmast.Sample.Pipe { public class Sample : System.Windows.Forms.Form { private Process p;
private System.Windows.Forms.RichTextBox tbResult; private System.Windows.Forms.Button btnExit; private System.Windows.Forms.Button btnRefresh;
private System.ComponentModel.Container components = null;
public Sample() { InitializeComponent(); Thread t = new Thread(new ThreadStart(Run)); tbResult.Text = "Processing..."; t.Start(); }
private void Run() { p = new Process(); p.StartInfo.FileName = "cmd.exe";
// 这里是关键点,不用Shell启动/重定向输入/重定向输出/不显示窗口 p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = true; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.CreateNoWindow = true;
p.Start(); p.StandardInput.WriteLine("ping 127.0.0.1");// 向cmd.exe输入command p.StandardInput.WriteLine("exit"); p.WaitForExit(60000); string s = p.StandardOutput.ReadToEnd();// 得到cmd.exe的输出 p.Close();
tbResult.Text = s.Replace("\r","").Replace("\n","\r\n"); }
protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); }
[STAThread] static void Main() { Application.Run(new Sample()); }
#region Windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this.tbResult = new System.Windows.Forms.RichTextBox(); this.btnExit = new System.Windows.Forms.Button(); this.btnRefresh = new System.Windows.Forms.Button(); this.SuspendLayout(); // // tbResult // this.tbResult.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.tbResult.BackColor = System.Drawing.SystemColors.Info; this.tbResult.Location = new System.Drawing.Point(8, 8); this.tbResult.Name = "tbResult"; this.tbResult.ReadOnly = true; this.tbResult.Size = new System.Drawing.Size(376, 424); this.tbResult.TabIndex = 0; this.tbResult.Text = ""; // // btnExit // this.btnExit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.btnExit.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnExit.Location = new System.Drawing.Point(320, 440); this.btnExit.Name = "btnExit"; this.btnExit.Size = new System.Drawing.Size(64, 24); this.btnExit.TabIndex = 1; this.btnExit.Text = "Exit"; this.btnExit.Click += new System.EventHandler(this.btnExit_Click); // // btnRefresh // this.btnRefresh.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.btnRefresh.Location = new System.Drawing.Point(248, 440); this.btnRefresh.Name = "btnRefresh"; this.btnRefresh.Size = new System.Drawing.Size(64, 24); this.btnRefresh.TabIndex = 2; this.btnRefresh.Text = "Refresh"; this.btnRefresh.Click += new System.EventHandler(this.btnRefresh_Click); // // Sample // this.AcceptButton = this.btnRefresh; this.AutoScaleBaseSize = new System.Drawing.Size(6, 14); this.CancelButton = this.btnExit; this.ClientSize = new System.Drawing.Size(392, 471); this.Controls.Add(this.btnRefresh); this.Controls.Add(this.btnExit); this.Controls.Add(this.tbResult); this.Name = "Sample"; this.Text = "Sample"; this.ResumeLayout(false);
} #endregion
private void btnExit_Click(object sender, System.EventArgs e) { Application.Exit(); }
private void btnRefresh_Click(object sender, System.EventArgs e) { this.Run(); } } } // 在Windows2003 Server, .NET Framework1.1.4322平台运行通过, VS.NET 2003调试通过.
怎么样, 很简单吧? 要是还不懂自己调试调试代码就明白啦. 关于Windows的PIPE技术本身, 可以看看这两篇文章: Windows管道技术简述 Windows系列操作系统对线程间通信的支持
我的BLOG: http://blog.sunmast.com/ 
|