衆所周知,C#以其高效的開發效率和完全面向對象的特性以及豐富的方法函數深受廣大程序員的喜愛,因此拿來做界面非常快捷方便,而有很多涉及算法的核心程序又是用別的語言開發的(如C++),如何通過C#的界面窗體程序調用已有的控制檯程序有很大的需求,這個需求都可以通過C#的Process類來實現,需要引用的名空間是System.Diagnostics,以下例子是現有一個控制檯程序,調用的參數比較複雜,具體爲DetectionWithShp.exe -ib c:\before.img -ia c:\after.img -s c:\tuban.shp -o output.shp,處理過程也比較久,會輸出很多提示進度的信息在控制檯,通過C#的界面,將-ib、-ia、-s、-o後面的參數以文件選擇的方式讀入,然後執行,並將控制檯的進度信息實時輸出至窗體的Listbox控件中。核心代碼是對Process的使用:
爲了設計一個結束被調用進程的按鈕,把Process p = new Process();的定義放在frmMain()中,啓動被調用程序的按鈕響應代碼如下:
{
string m_exename = Application.StartupPath + @"\DetectionWithShp.exe";
string m_space = " ";
string m_cmdLine;
m_cmdLine = " -ib " + txtImageBefore.Text +
" -ia " + txtImageAfter.Text +
" -s " + txtInputShp.Text +
" -o " + txtOutputShp.Text;
p.StartInfo.WorkingDirectory = Application.StartupPath; //可以手動設置啓動程序時的當前路徑,否則可能因爲OpenFileDialog操作而改變
p.StartInfo.FileName = m_exename;
p.StartInfo.Arguments = m_exename + m_cmdLine;
p.StartInfo.UseShellExecute = false; //必須爲false才能重定向輸出
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
p.Start();
p.BeginOutputReadLine();
}
其中DataReceivedEventHandler是自定義的一個接受輸出並處理的函數
private void p_OutputDataReceived(object sender,DataReceivedEventArgs e)
{
AddMessageHandler handler = delegate(string msg)
{
this.listboxStatus.Items.Add( msg + Environment.NewLine);
this.listboxStatus.SelectedIndex = listboxStatus.Items.Count - 1;
};
if (this.listboxStatus.InvokeRequired)
this.listboxStatus.Invoke(handler, e.Data);
}
結束進程的代碼如下:
{
{
p.Kill(); // 不能用Close(),官方解釋Close的作用是:Frees all the resources that are associated with this component.
}
}
這樣便可以實現調用帶複雜參數的控制檯程序,並將結果實時輸出至窗體的顯示控件中。