透過非同步的方式執行外部EXE檔案,並捕捉輸出字串

這篇文章沒有甚麼新奇之處,純粹整理出透過ASP.NET WebForm的架構,以非同步的方式運行外部執行檔(Exe),並將輸出的結果捕捉成字串,以非同步的方式送回並顯示,其中大部分的知識點是讓ASPX頁面可以執行非同步方法,等候回傳與顯示

ASP.NET WebForm非同步架構

Step 1. 首先,你必須在標題宣告<%@ Page Async="true" %>,這一步很重要。

Step 2. 然後我們設計一個透過非同步運行外部程序的方法,其中一律採用事件觸發來進行執行狀態與輸出的監控,並於運行後將輸出文字回送。

private async System.Threading.Tasks.Task<string> RunExternalProcessAsync()
{
  var oTask = new System.Threading.Tasks.TaskCompletionSource<string>();
  var oSB = new System.Text.StringBuilder();

  using var oProcess = new System.Diagnostics.Process()
  {
    StartInfo = new System.Diagnostics.ProcessStartInfo()
    {
      WorkingDirectory = @"D:\",  //沒寫可能會造成RedirectStandardOutput無法捕獲某些EXE的輸出
      FileName = @"D:\csc.exe",
      Arguments = @"something",
      UseShellExecute = false,
      CreateNoWindow = true,
      RedirectStandardOutput = true
    },
    EnableRaisingEvents = true
  };

  oProcess.OutputDataReceived += (s, e) => oSB.AppendLine(e.Data);
  oProcess.Exited += (s, e) =>
  {
    ((System.Diagnostics.Process)s).Close();
    oTask.TrySetResult(oSB.ToString());
  };

  oProcess.Start();
  oProcess.BeginOutputReadLine();

  return await oTask.Task;
}

Step 3. 撰寫非同步Page_Load,把回傳的字串顯示在網頁上。

public async void Page_Load(Object sender, EventArgs e)
{
  var cTemp = await RunExternalProcessAsync();
  cMsg.Text = $"<pre>{cTemp}</pre>";
}

整體的結構大概像這樣就可以運行了,網頁執行後會跑去運行外部EXE,如果運行時間長一點網站就會開始轉圈圈等候,當有輸出回應時就會自動將運行結果輸出在畫面上並結束。

相關參考

.NetFramework C# CallEXE CallExecute DetectHadFinish DetectHadExit WaitingTime DataExchange FileExchange FileReleased ResourceReleased Async Await