您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關C#中怎么調用外部進程,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
執行外部進程的函數
privatestringRunCmd(stringcommand) { //例Process Processp=newProcess(); p.StartInfo.FileName="cmd.exe";//確定程序名 p.StartInfo.Arguments="/c"+command;//確定程式命令行 p.StartInfo.UseShellExecute=false;//Shell的使用 p.StartInfo.RedirectStandardInput=true;//重定向輸入 p.StartInfo.RedirectStandardOutput=true;//重定向輸出 p.StartInfo.RedirectStandardError=true;//重定向輸出錯誤 p.StartInfo.CreateNoWindow=true;//設置置不顯示示窗口 p.Start();//00 //p.StandardInput.WriteLine(command);//也可以用這種方式輸入入要行的命令 //p.StandardInput.WriteLine("exit");//要得加上Exit要不然下一行程式 returnp.StandardOutput.ReadToEnd();//輸出出流取得命令行結果果 }
這個方法應該是比較常見的C#調用外部進程的方法,我以前也一直是這樣調用外部進程的,也沒有碰到過什么問題。但這次調用的外部進程比較特殊,用這種方法調用就出現了兩個問題。
***個問題是這個被調用的外部進程有時候會出現異常,出現異常后Windows會彈出錯誤報告框,程序于是吊死在那里,必須手工干預。這個問題比較好解決,程序中設置一下注冊表搞定。
第二個問題是C#調用外部進程(是一個控制臺進程)后,程序會阻塞在p.StandardOutput.ReadToEnd();這一句,永遠無法出來,被調用的那個控制臺程序也被吊死。但該控制臺進程在CMD 中是可以正常執行的。后來看來一些資料才發現原來原因是出在該控制臺程序控制臺輸出大量字符串,管道重定向后,調用程序沒有及時將管道中的輸出數據取出,結果導致管道被阻塞,程序吊死。在這里還有另外一個問題,雖然這次沒有遇到,但網上有其他人遇到,就是錯誤信息管道不及時取出數據,也會被阻塞,而且如果要同時取出兩個管道的數據,必須要利用一個輔助線程才能實現。
問題講完了,下面給出這個類的完整代碼
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.Runtime.InteropServices;
usingSystem.Threading;
namespaceLaboratory.Process
{
classReadErrorThread
{
System.Threading.Threadm_Thread;
System.Diagnostics.Processm_Process;
Stringm_Error;
boolm_HasExisted;
objectm_LockObj=newobject();
publicStringError
{
get
{
returnm_Error;
}
}
publicboolHasExisted
{
get
{
lock(m_LockObj)
{
returnm_HasExisted;
}
}
set
{
lock(m_LockObj)
{
m_HasExisted=value;
}
}
}
privatevoidReadError()
{
StringBuilderstrError=newStringBuilder();
while(!m_Process.HasExited)
{
strError.Append(m_Process.StandardError.ReadLine());
}
strError.Append(m_Process.StandardError.ReadToEnd());
m_Error=strError.ToString();
HasExisted=true;
}
publicReadErrorThread(System.Diagnostics.Processp)
{
HasExisted=false;
m_Error="";
m_Process=p;
m_Thread=newThread(newThreadStart(ReadError));
m_Thread.Start();
}
}
classRunProcess
{
privateStringm_Error;
privateStringm_Output;
publicStringError
{
get
{
returnm_Error;
}
}
publicStringOutput
{
get
{
returnm_Output;
}
}
publicboolHasError
{
get
{
returnm_Error!=""&&m_Error!=null;
}
}
publicvoidRun(StringfileName,Stringpara)
{
StringBuilderoutputStr=newStringBuilder();
try
{
//disabletheerrorreportdialog.
//reference:http://www.devcow.com/blogs/adnrg/archive/2006/07/14/
Disable-Error-Reporting-Dialog-for-your-application-with-the-registry.aspxMicrosoft.Win32.RegistryKeykey;
key=Microsoft.Win32.Registry.LocalMachine.OpenSubKey
(@"software\microsoft\PCHealth\ErrorReporting\",true);intdoReport=(int)key.GetValue("DoReport");
if(doReport!=0)
{
key.SetValue("DoReport",0);
}
intshowUI=(int)key.GetValue("ShowUI");
if(showUI!=0)
{
key.SetValue("ShowUI",0);
}
}
catch
{
}
m_Error="";
m_Output="";
try
{
System.Diagnostics.Processp=newSystem.Diagnostics.Process();
p.StartInfo.FileName=fileName;
p.StartInfo.Arguments=para;
p.StartInfo.UseShellExecute=false;
p.StartInfo.RedirectStandardInput=true;
p.StartInfo.RedirectStandardOutput=true;
p.StartInfo.RedirectStandardError=true;
p.StartInfo.CreateNoWindow=true;
p.Start();
ReadErrorThreadreadErrorThread=newReadErrorThread(p);
while(!p.HasExited)
{
outputStr.Append(p.StandardOutput.ReadLine()+"\r\n");
}
outputStr.Append(p.StandardOutput.ReadToEnd());
while(!readErrorThread.HasExisted)
{
Thread.Sleep(1);
}
m_Error=readErrorThread.Error;
m_Output=outputStr.ToString();
}
catch(Exceptione)
{
m_Error=e.Message;
}
}
}
}
以上就是C#中怎么調用外部進程,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。