一個執行Dos命令的窗口程序,與各位分享。
效果圖: 具體實現在代碼中有詳細的注釋,請看代碼。 實現執行CMD命令的核心代碼(Cmd.cs): [csharp] using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.Threading; using System.Management; using System.Globalization; namespace Zbsoft.ExtendFunction { public class Cmd { /// <summary> /// 是否終止調用CMD命令執行 /// </summary> private static bool invokeCmdKilled = true; /// <summary> /// 獲取或設置是否終止調用CMD命令執行 /// </summary> public static bool InvokeCmdKilled { get { return invokeCmdKilled; } set { invokeCmdKilled = value; if (invokeCmdKilled) { if (p != null && !p.HasExited) { killProcess(p.Id); } } } } private static Process p; private static Action<string> RefreshResult; /// <summary> /// 調用CMD命令,執行指定的命令,並返回命令執行返回結果字符串 /// </summary> /// <param name="cmdArgs">命令行</param> /// <param name="RefreshResult">刷新返回結果字符串的事件</param> /// <returns></returns> public static void InvokeCmd(string cmdArgs, Action<string> pRefreshResult = null) { InvokeCmdKilled = false; RefreshResult = pRefreshResult; if (p != null) { p.Close(); p = null; } p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived); p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived); p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = true; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.CreateNoWindow = true; p.Start(); p.BeginErrorReadLine(); p.BeginOutputReadLine(); string[] cmds = cmdArgs.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var v in cmds) { Thread.Sleep(200); p.StandardInput.WriteLine(v); } //p.StandardInput.WriteLine("exit"); p.WaitForExit(); p.Dispose(); p.Close(); p = null; InvokeCmdKilled = true; } /// <summary> /// 輸入交互式命令 /// </summary> /// <param name="cmd"></param> public static void InputCmdLine(string cmd) { if (p == null) return; string[] cmds = cmd.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var v in cmds) { Thread.Sleep(200); p.StandardInput.WriteLine(v); } } /// <summary> /// 異步讀取標准輸出信息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> static void p_OutputDataReceived(object sender, DataReceivedEventArgs e) { if (RefreshResult != null && e.Data != null) RefreshResult(e.Data + "\r\n"); } /// <summary> /// 異步讀取錯誤消息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> static void p_ErrorDataReceived(object sender, DataReceivedEventArgs e) { if (RefreshResult != null && e.Data != null) { RefreshResult(e.Data + "\r\n"); } } /// <summary> /// 關閉指定進程ID的進程以及子進程(關閉進程樹) /// </summary> /// <param name="id"></param> public static void FindAndKillProcess(int id) { killProcess(id); } /// <summary> /// 關閉指定進程名稱的進程以及子進程(關閉進程樹) /// </summary> /// <param name="name"></param> public static void FindAndKillProcess(string name) { foreach (Process clsProcess in Process.GetProcesses()) { if ((clsProcess.ProcessName.StartsWith(name, StringComparison.CurrentCulture)) || (clsProcess.MainWindowTitle.StartsWith(name, StringComparison.CurrentCulture))) killProcess(clsProcess.Id); } } /// <summary> /// 關閉進程樹 /// </summary> /// <param name="pid"></param> /// <returns></returns> private static bool killProcess(int pid) { Process[] procs = Process.GetProcesses(); for (int i = 0; i < procs.Length; i++) { if (getParentProcess(procs[i].Id) == pid) killProcess(procs[i].Id); } try { Process myProc = Process.GetProcessById(pid); myProc.Kill(); } //進程已經退出 catch (ArgumentException) { ; } return true; } /// <summary> /// 獲取父進程ID /// </summary> /// <param name="Id"></param> /// <returns></returns> private static int getParentProcess(int Id) { int parentPid = 0; using (ManagementObject mo = new ManagementObject("win32_process.handle='" + Id.ToString(CultureInfo.InvariantCulture) + "'")) { try { mo.Get(); } catch (ManagementException) { return -1; } parentPid = Convert.ToInt32(mo["ParentProcessId"], CultureInfo.InvariantCulture); } return parentPid; } } } 調用上述核心類的窗口代碼(Form2.cs): [csharp] using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; namespace Zbsoft.Test { public partial class Form2 : Form { Thread cmdThread; private Action<string> rf; public Form2() { InitializeComponent(); } /// <summary> /// 按CTRL+Enter鍵開始執行命令 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void textBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { if (e.KeyCode == Keys.Enter && e.Control) { if (this.button3.Enabled) this.button3_Click(null, null); else this.button4_Click(null, null); } } private void Form2_Load(object sender, EventArgs e) { this.textBox1.Text = "help\r\ndir\r\nping 127.0.0.1"; rf = this.refreshCmdTxt; this.richTextBox1.AppendText("Dos命令執行程序,支持批命令執行。按Ctrl+Enter鍵開始執行。如果一個命令長時間不能結束的,如ping 127.0.0.1 -t,“停止執行”按鈕可強制終止執行。\r\n"); this.richTextBox1.AppendText("\r\n你的網卡Mac地址:" + Zbsoft.ExtendFunction.HardwareInfo.getID_NetCardId()); this.richTextBox1.AppendText(",Cpu序列號:" + Zbsoft.ExtendFunction.HardwareInfo.getID_CpuId()); this.richTextBox1.AppendText(",硬盤序列號:" + Zbsoft.ExtendFunction.HardwareInfo.getID_HardDiskId() + "\r\n"); this.richTextBox1.AppendText("\r\n常用的命令:\r\n"); this.richTextBox1.AppendText(@" ASSOC 顯示或修改文件擴展名關聯。 ATTRIB 顯示或更改文件屬性。 BREAK 設置或清除擴展式 CTRL+C 檢查。 BCDEDIT 設置啟動數據庫中的屬性以控制啟動加載。 CACLS 顯示或修改文件的訪問控制列表(ACL)。 CALL 從另一個批處理程序調用這一個。 CD 顯示當前目錄的名稱或將其更改。 CHCP 顯示或設置活動代碼頁數。 CHDIR 顯示當前目錄的名稱或將其更改。 CHKDSK 檢查磁盤並顯示狀態報告。 CHKNTFS 顯示或修改啟動時間磁盤檢查。 CLS 清除屏幕。 CMD 打開另一個 Windows 命令解釋程序窗口。 COLOR 設置默認控制台前景和背景顏色。 COMP 比較兩個或兩套文件的內容。 COMPACT 顯示或更改 NTFS 分區上文件的壓縮。 CONVERT 將 FAT 卷轉換成 NTFS。您不能轉換當前驅動器。 COPY 將至少一個文件復制到另一個位置。 DATE 顯示或設置日期。 DEL 刪除至少一個文件。 DIR 顯示一個目錄中的文件和子目錄。 DISKCOMP 比較兩個軟盤的內容。 DISKCOPY 將一個軟盤的內容復制到另一個軟盤。 DISKPART 顯示或配置磁盤分區屬性。 DOSKEY 編輯命令行、調用 Windows 命令並創建宏。 DRIVERQUERY 顯示當前設備驅動程序狀態和屬性。 ECHO 顯示消息,或將命令回顯打開或關上。 ENDLOCAL 結束批文件中環境更改的本地化。 ERASE 刪除一個或多個文件。 EXIT 退出 CMD.EXE 程序(命令解釋程序)。 FC 比較兩個文件或兩個文件集並顯示它們之間的不同。 FIND 在一個或多個文件中搜索一個文本字符串。 FINDSTR 在多個文件中搜索字符串。 FOR 為一套文件中的每個文件運行一個指定的命令。 FORMAT 格式化磁盤,以便跟 Windows 使用。 FSUTIL 顯示或配置文件系統的屬性。 FTYPE 顯示或修改用在文件擴展名關聯的文件類型。 GOTO 將 Windows 命令解釋程序指向批處理程序中某個帶標簽的行。 GPRESULT 顯示機器或用戶的組策略信息。 GRAFTABL 啟用 Windows 在圖形模式顯示擴展字符集。 HELP 提供 Windows 命令的幫助信息。 ICACLS 顯示、修改、備份或還原文件和目錄的 ACL。 IF 在批處理程序中執行有條件的處理過程。 IPCONFIG 網絡配置 LABEL 創建、更改或刪除磁盤的卷標。 MD 創建一個目錄。 MKDIR 創建一個目錄。 MKLINK 創建符號鏈接和硬鏈接 MODE 配置系統設備。 MORE 逐屏顯示輸出。 MOVE 將一個或多個文件從一個目錄移動到另一個目錄。 NET 這個命令太強大了,net help自己看看吧 NETSTAT 網絡狀態 OPENFILES 顯示遠程用戶為了文件共享而打開的文件。 PATH 為可執行文件顯示或設置搜索路徑。 PAUSE 停止批處理文件的處理並顯示信息。 PING 檢測網絡是否通暢 POPD 還原由 PUSHD 保存的當前目錄上一次的值。 PRINT 打印一個文本文件。 PROMPT 改變 Windows 命令提示。 PUSHD 保存當前目錄,然後對其進行更改。 RD 刪除目錄。 RECOVER 從損壞的磁盤中恢復可讀取的信息。 REM 記錄批處理文件或 CONFIG.SYS 中的注釋。 REN 重新命名文件。 RENAME 重新命名文件。 REPLACE 替換文件。 RMDIR 刪除目錄。 ROBOCOPY 復制文件和目錄樹的高級實用程序 ROUTE 路由命令 SET 顯示、設置或刪除 Windows 環境變量。 SETLOCAL 開始用批文件改變環境的本地化。 SC 顯示或配置服務(後台處理)。 SCHTASKS 安排命令和程序在一部計算機上按計劃運行。 SHIFT 調整批處理文件中可替換參數的位置。 SHUTDOWN 讓機器在本地或遠程正確關閉。 SORT 將輸入排序。 START 打開單獨視窗運行指定程序或命令。 SUBST 將驅動器號與路徑關聯。 SYSTEMINFO 顯示機器的具體的屬性和配置。 TASKLIST 顯示包括服務的所有當前運行的任務。 TASKKILL 終止正在運行的進程或應用程序。 TIME 顯示或設置系統時間。 TITLE 設置 CMD.EXE 會話的窗口標題。 TRACERT 用於將數據包從計算機傳遞到目標位置的一組IP路由器,以及每個躍點所需的時間。 TREE 以圖形顯示啟動器或路徑的目錄結構。 TYPE 顯示文本文件的內容。 VER 顯示 Windows 的版本。 VERIFY 告訴 Windows 驗證文件是否正確寫入磁盤。 VOL 顯示磁盤卷標和序列號。 XCOPY 復制文件和目錄樹。 WMIC 在交互命令外殼裡顯示 WMI 信息。"); } private void StartCmd() { Zbsoft.ExtendFunction.Cmd.InvokeCmd(this.textBox1.Text, this.refreshCmdTxt); } /// <summary> /// 顯示返回結果 /// </summary> /// <param name="txt"></param> private void refreshCmdTxt(string txt) { if (!this.Visible) return; if (this.richTextBox1.InvokeRequired) { try { this.richTextBox1.Invoke(this.rf, txt); } catch { } } else { this.richTextBox1.AppendText(txt); this.richTextBox1.ScrollToCaret(); } } /// <summary> /// 停止執行 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { Zbsoft.ExtendFunction.Cmd.InvokeCmdKilled = true; this.button3.Enabled = true; } /// <summary> /// 清空返回結果 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, EventArgs e) { this.richTextBox1.Clear(); } /// <summary> /// 開始執行命令 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button3_Click(object sender, EventArgs e) { if (cmdThread != null && !Zbsoft.ExtendFunction.Cmd.InvokeCmdKilled) { MessageBox.Show("程序正在執行中,請稍候或中止後再執行!"); return; } if (string.IsNullOrEmpty(this.textBox1.Text)) return; if (cmdThread != null) { cmdThread.Abort(); cmdThread = null; } cmdThread = new Thread(StartCmd); cmdThread.Start(); this.button3.Enabled = false; } private void Form2_FormClosed(object sender, FormClosedEventArgs e) { if (cmdThread != null) { cmdThread.Abort(); cmdThread = null; } } /// <summary> /// 輸入交互式命令 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button4_Click(object sender, EventArgs e) { if (cmdThread == null) return; Zbsoft.ExtendFunction.Cmd.InputCmdLine(this.textBox1.Text); } /// <summary> /// 輸入退出命令 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button5_Click(object sender, EventArgs e) { if (cmdThread == null) return; Zbsoft.ExtendFunction.Cmd.InputCmdLine("exit"); this.button3.Enabled = true; } private void Form2_FormClosing(object sender, FormClosingEventArgs e) { Zbsoft.ExtendFunction.Cmd.InvokeCmdKilled = true; } } } 窗口文件:Form2.Designer.cs [csharp] view plaincopy namespace Zbsoft.Test { partial class Form2 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.textBox1 = new System.Windows.Forms.TextBox(); this.richTextBox1 = new System.Windows.Forms.RichTextBox(); this.label1 = new System.Windows.Forms.Label(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); this.button3 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); this.button1 = new System.Windows.Forms.Button(); this.button4 = new System.Windows.Forms.Button(); this.button5 = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); this.splitContainer1.SuspendLayout(); this.SuspendLayout(); // // textBox1 // this.textBox1.AutoCompleteCustomSource.AddRange(new string[] { "ASSOC", "ATTRIB", "BREAK", "BCDEDIT", "CACLS", "CALL", "CD", "CHCP", "CHDIR", "CHKDSK", "CHKNTFS", "CLS", "CMD", "COLOR", "COMP", "COMPACT", "CONVERT", "COPY", "DATE", "DEL", "DIR", "DISKCOMP", "DISKCOPY", "DISKPART", "DOSKEY", "DRIVERQUERY", "ECHO", "ENDLOCAL", "ERASE", "EXIT", "FC", "FIND", "FINDSTR", "FOR", "FORMAT", "FSUTIL", "FTYPE", "GOTO", "GPRESULT", "GRAFTABL", "HELP", "ICACLS", "IF", "LABEL", "MD", "MKDIR", "MKLINK", "MODE", "MORE", "MOVE", "OPENFILES", "PATH", "PAUSE", "POPD", "PRINT", "PROMPT", "PUSHD", "RD", "RECOVER", "REM", "REN", "RENAME", "REPLACE", "RMDIR", "ROBOCOPY", "SET", "SETLOCAL", "SC", "SCHTASKS", "SHIFT", "SHUTDOWN", "SORT", "START", "SUBST", "SYSTEMINFO", "TASKLIST", "TASKKILL", "TIME", "TITLE", "TREE", "TYPE", "VER", "VERIFY", "VOL", "XCOPY", "WMIC"}); this.textBox1.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Append; this.textBox1.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.CustomSource; this.textBox1.Dock = System.Windows.Forms.DockStyle.Bottom; this.textBox1.Location = new System.Drawing.Point(5, 38); this.textBox1.Multiline = true; this.textBox1.Name = "textBox1"; this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both; this.textBox1.Size = new System.Drawing.Size(838, 53); this.textBox1.TabIndex = 0; this.textBox1.Text = "ping 10.84.184.1 -t"; this.textBox1.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.textBox1_PreviewKeyDown); // // richTextBox1 // this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill; this.richTextBox1.Location = new System.Drawing.Point(5, 5); this.richTextBox1.Name = "richTextBox1"; this.richTextBox1.Size = new System.Drawing.Size(838, 289); this.richTextBox1.TabIndex = 1; this.richTextBox1.Text = ""; // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(7, 14); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(173, 12); this.label1.TabIndex = 2; this.label1.Text = "請輸入待執行的命令,回車執行"; // // splitContainer1 // this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; this.splitContainer1.Location = new System.Drawing.Point(0, 0); this.splitContainer1.Name = "splitContainer1"; this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; // // splitContainer1.Panel1 // this.splitContainer1.Panel1.Controls.Add(this.button5); this.splitContainer1.Panel1.Controls.Add(this.button4); this.splitContainer1.Panel1.Controls.Add(this.button3); this.splitContainer1.Panel1.Controls.Add(this.button2); this.splitContainer1.Panel1.Controls.Add(this.button1); this.splitContainer1.Panel1.Controls.Add(this.textBox1); this.splitContainer1.Panel1.Controls.Add(this.label1); this.splitContainer1.Panel1.Padding = new System.Windows.Forms.Padding(5, 0, 5, 5); // // splitContainer1.Panel2 // this.splitContainer1.Panel2.Controls.Add(this.richTextBox1); this.splitContainer1.Panel2.Padding = new System.Windows.Forms.Padding(5); this.splitContainer1.Size = new System.Drawing.Size(848, 399); this.splitContainer1.SplitterDistance = 96; this.splitContainer1.TabIndex = 3; // // button3 // this.button3.Location = new System.Drawing.Point(231, 9); this.button3.Name = "button3"; this.button3.Size = new System.Drawing.Size(75, 23); this.button3.TabIndex = 5; this.button3.Text = "開始執行"; this.button3.UseVisualStyleBackColor = true; this.button3.Click += new System.EventHandler(this.button3_Click); // // button2 // this.button2.Location = new System.Drawing.Point(605, 9); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(95, 23); this.button2.TabIndex = 4; this.button2.Text = "清空返回結果"; this.button2.UseVisualStyleBackColor = true; this.button2.Click += new System.EventHandler(this.button2_Click); // // button1 // this.button1.Location = new System.Drawing.Point(511, 9); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(75, 23); this.button1.TabIndex = 3; this.button1.Text = "停止執行"; this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.button1_Click); // // button4 // this.button4.Location = new System.Drawing.Point(320, 9); this.button4.Name = "button4"; this.button4.Size = new System.Drawing.Size(75, 23); this.button4.TabIndex = 6; this.button4.Text = "交互輸入"; this.button4.UseVisualStyleBackColor = true; this.button4.Click += new System.EventHandler(this.button4_Click); // // button5 // this.button5.Location = new System.Drawing.Point(405, 9); this.button5.Name = "button5"; this.button5.Size = new System.Drawing.Size(94, 23); this.button5.TabIndex = 7; this.button5.Text = "輸入退出命令"; this.button5.UseVisualStyleBackColor = true; this.button5.Click += new System.EventHandler(this.button5_Click); // // Form2 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(848, 399); this.Controls.Add(this.splitContainer1); this.Name = "Form2"; this.Text = "Dos Command"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form2_FormClosing); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form2_FormClosed); this.Load += new System.EventHandler(this.Form2_Load); this.splitContainer1.Panel1.ResumeLayout(false); this.splitContainer1.Panel1.PerformLayout(); this.splitContainer1.Panel2.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); this.splitContainer1.ResumeLayout(false); this.ResumeLayout(false); } #endregion private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.RichTextBox richTextBox1; private System.Windows.Forms.Label label1; private System.Windows.Forms.SplitContainer splitContainer1; private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; private System.Windows.Forms.Button button3; private System.Windows.Forms.Button button5; private System.Windows.Forms.Button button4; } }