溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C#中怎么調(diào)用外部進(jìn)程

發(fā)布時(shí)間:2021-06-24 16:24:48 來源:億速云 閱讀:305 作者:Leah 欄目:編程語言

本篇文章給大家分享的是有關(guān)C#中怎么調(diào)用外部進(jìn)程,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

執(zhí)行外部進(jìn)程的函數(shù)

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;//重定向輸出錯(cuò)誤  p.StartInfo.CreateNoWindow=true;//設(shè)置置不顯示示窗口   p.Start();//00   //p.StandardInput.WriteLine(command);//也可以用這種方式輸入入要行的命令  //p.StandardInput.WriteLine("exit");//要得加上Exit要不然下一行程式   returnp.StandardOutput.ReadToEnd();//輸出出流取得命令行結(jié)果果   }

這個(gè)方法應(yīng)該是比較常見的C#調(diào)用外部進(jìn)程的方法,我以前也一直是這樣調(diào)用外部進(jìn)程的,也沒有碰到過什么問題。但這次調(diào)用的外部進(jìn)程比較特殊,用這種方法調(diào)用就出現(xiàn)了兩個(gè)問題。

***個(gè)問題是這個(gè)被調(diào)用的外部進(jìn)程有時(shí)候會(huì)出現(xiàn)異常,出現(xiàn)異常后Windows會(huì)彈出錯(cuò)誤報(bào)告框,程序于是吊死在那里,必須手工干預(yù)。這個(gè)問題比較好解決,程序中設(shè)置一下注冊(cè)表搞定。

第二個(gè)問題是C#調(diào)用外部進(jìn)程(是一個(gè)控制臺(tái)進(jìn)程)后,程序會(huì)阻塞在p.StandardOutput.ReadToEnd();這一句,永遠(yuǎn)無法出來,被調(diào)用的那個(gè)控制臺(tái)程序也被吊死。但該控制臺(tái)進(jìn)程在CMD 中是可以正常執(zhí)行的。后來看來一些資料才發(fā)現(xiàn)原來原因是出在該控制臺(tái)程序控制臺(tái)輸出大量字符串,管道重定向后,調(diào)用程序沒有及時(shí)將管道中的輸出數(shù)據(jù)取出,結(jié)果導(dǎo)致管道被阻塞,程序吊死。在這里還有另外一個(gè)問題,雖然這次沒有遇到,但網(wǎng)上有其他人遇到,就是錯(cuò)誤信息管道不及時(shí)取出數(shù)據(jù),也會(huì)被阻塞,而且如果要同時(shí)取出兩個(gè)管道的數(shù)據(jù),必須要利用一個(gè)輔助線程才能實(shí)現(xiàn)。

問題講完了,下面給出這個(gè)類的完整代碼

  1. usingSystem;  

  2. usingSystem.Collections.Generic;  

  3. usingSystem.Text;  

  4. usingSystem.Runtime.InteropServices;  

  5. usingSystem.Threading;  

  6.  

  7. namespaceLaboratory.Process  

  8. {  

  9. classReadErrorThread  

  10. {  

  11. System.Threading.Threadm_Thread;  

  12. System.Diagnostics.Processm_Process;  

  13. Stringm_Error;  

  14. boolm_HasExisted;  

  15. objectm_LockObj=newobject();  

  16.  

  17. publicStringError  

  18. {  

  19. get  

  20. {  

  21. returnm_Error;  

  22. }  

  23. }  

  24.  

  25. publicboolHasExisted  

  26. {  

  27. get  

  28. {  

  29. lock(m_LockObj)  

  30. {  

  31. returnm_HasExisted;  

  32. }  

  33. }  

  34.  

  35. set  

  36. {  

  37. lock(m_LockObj)  

  38. {  

  39. m_HasExisted=value;  

  40. }  

  41. }  

  42. }  

  43.  

  44. privatevoidReadError()  

  45. {  

  46. StringBuilderstrError=newStringBuilder();  

  47. while(!m_Process.HasExited)  

  48. {  

  49. strError.Append(m_Process.StandardError.ReadLine());  

  50. }  

  51.  

  52. strError.Append(m_Process.StandardError.ReadToEnd());  

  53.  

  54. m_Error=strError.ToString();  

  55. HasExisted=true;  

  56. }  

  57.  

  58. publicReadErrorThread(System.Diagnostics.Processp)  

  59. {  

  60. HasExisted=false;  

  61. m_Error="";  

  62. m_Process=p;  

  63. m_Thread=newThread(newThreadStart(ReadError));  

  64. m_Thread.Start();  

  65. }  

  66.  

  67. }  

  68.  

  69. classRunProcess  

  70. {  

  71. privateStringm_Error;  

  72. privateStringm_Output;  

  73.  

  74. publicStringError  

  75. {  

  76. get  

  77. {  

  78. returnm_Error;  

  79. }  

  80. }  

  81.  

  82. publicStringOutput  

  83. {  

  84. get  

  85. {  

  86. returnm_Output;  

  87. }  

  88. }  

  89.  

  90. publicboolHasError  

  91. {  

  92. get  

  93. {  

  94. returnm_Error!=""&&m_Error!=null;  

  95. }  

  96. }  

  97.  

  98. publicvoidRun(StringfileName,Stringpara)  

  99. {  

  100. StringBuilderoutputStr=newStringBuilder();  

  101.  

  102. try  

  103. {  

  104. //disabletheerrorreportdialog.  

  105. //reference:http://www.devcow.com/blogs/adnrg/archive/2006/07/14/
    Disable-Error-Reporting-Dialog-for-your-application-with-the-registry.aspx  

  106. Microsoft.Win32.RegistryKeykey;  

  107. key=Microsoft.Win32.Registry.LocalMachine.OpenSubKey
    (@"software\microsoft\PCHealth\ErrorReporting\",true);  

  108. intdoReport=(int)key.GetValue("DoReport");  

  109.  

  110. if(doReport!=0)  

  111. {  

  112. key.SetValue("DoReport",0);  

  113. }  

  114.  

  115. intshowUI=(int)key.GetValue("ShowUI");  

  116. if(showUI!=0)  

  117. {  

  118. key.SetValue("ShowUI",0);  

  119. }  

  120. }  

  121. catch  

  122. {  

  123. }  

  124.  

  125.  

  126. m_Error="";  

  127. m_Output="";  

  128. try  

  129. {  

  130. System.Diagnostics.Processp=newSystem.Diagnostics.Process();  

  131.  

  132. p.StartInfo.FileName=fileName;  

  133. p.StartInfo.Arguments=para;  

  134. p.StartInfo.UseShellExecute=false;  

  135. p.StartInfo.RedirectStandardInput=true;  

  136. p.StartInfo.RedirectStandardOutput=true;  

  137. p.StartInfo.RedirectStandardError=true;  

  138. p.StartInfo.CreateNoWindow=true;  

  139.  

  140. p.Start();  

  141.  

  142. ReadErrorThreadreadErrorThread=newReadErrorThread(p);  

  143.  

  144. while(!p.HasExited)  

  145. {  

  146. outputStr.Append(p.StandardOutput.ReadLine()+"\r\n");  

  147. }  

  148.  

  149. outputStr.Append(p.StandardOutput.ReadToEnd());  

  150.  

  151. while(!readErrorThread.HasExisted)  

  152. {  

  153. Thread.Sleep(1);  

  154. }  

  155.  

  156. m_Error=readErrorThread.Error;  

  157. m_Output=outputStr.ToString();  

  158. }  

  159. catch(Exceptione)  

  160. {  

  161. m_Error=e.Message;  

  162. }  

  163. }  

  164.  

  165. }  

  166. }  

以上就是C#中怎么調(diào)用外部進(jìn)程,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI