C#输入输出重定向
當(dāng)?Process?將文本寫(xiě)入其標(biāo)準(zhǔn)流中時(shí),通常將在控制臺(tái)上顯示該文本。通過(guò)重定向?StandardOutput?流,可以操作或取消進(jìn)程的輸出。例如,可以篩選文本、用不同方式將其格式化,也可以將輸出同時(shí)寫(xiě)入控制臺(tái)和指定的日志文件中。有兩種方式:同步、異步。
?
1.??????先說(shuō)同步方法,這種方法網(wǎng)上有很多例子,廢話少說(shuō),貼上代碼大家一看就明白了:
????Process?process =?new?Process();
??? process.StartInfo.FileName =?"cmd.exe";
??? process.StartInfo.UseShellExecute =?false;???//?是否使用外殼程序?
??? process.StartInfo.CreateNoWindow =?true;???//是否在新窗口中啟動(dòng)該進(jìn)程的值?
??? process.StartInfo.RedirectStandardInput =?true;??//?重定向輸入流?
????//process.StartInfo.RedirectStandardOutput= true;? //重定向輸出流?
????//process.StartInfo.RedirectStandardError= true;? //重定向錯(cuò)誤流?
????string strCmd =?"ping www.163.com /r/n";
??? strCmd +=?"exit";
?
??? process.Start();
??? process.StandardInput.WriteLine(strCmd);
????string?output = process.StandardOutput.ReadToEnd();//獲取輸出信息?
??? process.WaitForExit();
????int?n =process.ExitCode;??// n?為進(jìn)程執(zhí)行返回值?
??? process.Close();
可以同步或異步讀取重定向的?StandardOutput?流。Read、ReadLine?和?ReadToEnd?等方法對(duì)進(jìn)程的輸出流執(zhí)行同步讀取操作。這些同步讀取操作只有在關(guān)聯(lián)的?Process?寫(xiě)入其StandardOutput?流或關(guān)閉該流后才能完成。
同步讀取操作在讀取?StandardOutput?流的調(diào)用方及寫(xiě)入該流中的子進(jìn)程之間引入一個(gè)依賴項(xiàng)。這些依賴項(xiàng)可能導(dǎo)致產(chǎn)生死鎖情況。調(diào)用方讀取子進(jìn)程的重定向流時(shí)依賴于該子進(jìn)程。調(diào)用方將等待讀取操作,直到子進(jìn)程寫(xiě)入流或關(guān)閉流為止。子進(jìn)程寫(xiě)入足夠多的數(shù)據(jù)以填充重定向流的時(shí)間依賴于父進(jìn)程。子進(jìn)程將等待下一次寫(xiě)操作,直到父進(jìn)程讀取了全部流或關(guān)閉該流為止。當(dāng)調(diào)用方和子進(jìn)程相互等待對(duì)方完成操作時(shí),就會(huì)產(chǎn)生死鎖情況,使雙方都無(wú)法繼續(xù)執(zhí)行操作。可以通過(guò)計(jì)算調(diào)用方和子進(jìn)程之間的依賴項(xiàng)從而避免出現(xiàn)死鎖情況。
2.??????再來(lái)說(shuō)一下異步方法
使用事件和委托,進(jìn)程有2個(gè)事件OutputDataReceived、OutputDataReceived。
我們可以注冊(cè)這2個(gè)事件,使該進(jìn)程在往Output和error流中填充數(shù)據(jù)時(shí),調(diào)用相應(yīng)的事件響應(yīng)函數(shù),及時(shí)處理流中數(shù)據(jù),從而避免流被填滿而發(fā)生的死鎖情況,在WaitForExit之前調(diào)用BeginOutputReadLine?或者BeginErrorReadLine?開(kāi)始異步讀取。此方法會(huì)為流輸出啟用一個(gè)指定的事件處理程序并立即返回到調(diào)用方,這樣當(dāng)流輸出被定向到該事件處理程序時(shí),調(diào)用方還可以執(zhí)行其他操作。
注意 |
若要使用?StandardOutput,必須將?ProcessStartInfo.UseShellExecute?設(shè)置為?false,并且將?ProcessStartInfo.RedirectStandardOutput?設(shè)置為?true。否則,讀取StandardOutput?流時(shí)將引發(fā)異常。 |
?
//?using?System.Diagnostics;
?
????//?運(yùn)行新進(jìn)程
????ProcessStartInfo?startInfo =new?ProcessStartInfo(exeName);
??? startInfo.CreateNoWindow =?true;???//不創(chuàng)建窗口
??? startInfo.UseShellExecute =?false;//不使用系統(tǒng)外殼程序啟動(dòng),重定向輸出的話必須設(shè)為false
??? startInfo.RedirectStandardOutput =?true;?//重定向輸出,而不是默認(rèn)的顯示在dos控制臺(tái)上
??? startInfo.RedirectStandardError =?true;
?
????try
??? {
????????Process?process =?Process.Start(startInfo);
??????? process.OutputDataReceived += (s, _e)=> Console.WriteLine(_e.Data);
??????? process.ErrorDataReceived += (s, _e) =>Console.WriteLine(_e.Data);
????????//當(dāng)EnableRaisingEvents為true,進(jìn)程退出時(shí)Process會(huì)調(diào)用下面的委托函數(shù)
??????? process.Exited += (s, _e) => Console.WriteLine("Exited with "?+ _process.ExitCode);
??????? process.EnableRaisingEvents =?true;
??????? process.BeginOutputReadLine();
??????? process.BeginErrorReadLine();
??????? process.WaitForExit();
??? }
????catch?(Exception?e)
??? {
??? Console.WriteLine(ex.Message);
}
?
?
3.??????注意事項(xiàng)
不能對(duì)同一個(gè)重定向流混合使用異步和同步讀取操作。在異步或同步模式下打開(kāi)?Process?的重定向流后,對(duì)該流的所有進(jìn)一步的讀取操作都必須在同一模式下進(jìn)行。例如,不要對(duì)StandardOutput?流調(diào)用BeginOutputReadLine?后接著調(diào)用ReadLine,反之亦然。但是,可以在不同的模式下讀取兩個(gè)不同的流。例如,可以先調(diào)用BeginOutputReadLine,然后再為StandardError?流調(diào)用?ReadLine。
總結(jié)
- 上一篇: android 实体对象转 json,l
- 下一篇: C#串口SerialPort常用属性方法