簡體   English   中英

從 ASP.NET 啟動外部進程

[英]Starting external process from ASP.NET

我需要從我的 Web 應用程序啟動一個外部進程。 這意味着使用System.Diagnostics.ProcessStartInfo調用並執行控制台應用程序 (exe)。 但是我需要以某種方式確保它在執行過程中沒有出現任何問題並知道應用程序何時完成其工作。

捕獲所有可能的錯誤並找出何時完成的最佳方法是什么?

Process 類並不難。 不過,之前的海報是正確的 - 您需要關注權限。

private string RunProcess(string cmd)
{
  System.Diagnostics.Process p; 
  p= new System.Diagnostics.Process();
  if (cmd== null || cmd=="") {
    return "no command given.";
  }
  string[] args= cmd.Split(new char[]{' '});
  if (args== null || args.Length==0 || args[0].Length==0) {
    return "no command provided.";
  }
  p.StartInfo.FileName= args[0];

  if (args.Length>1) {
    int startPoint= cmd.IndexOf(' ');
    string s= cmd.Substring(startPoint, cmd.Length-startPoint);
    p.StartInfo.Arguments= s; 
  }
  p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
  p.StartInfo.RedirectStandardOutput = true;
  p.StartInfo.UseShellExecute = false;

  p.Start();

  // must have the readToEnd BEFORE the WaitForExit(), to avoid a deadlock condition
  string output= p.StandardOutput.ReadToEnd();
  p.WaitForExit();

  return output; 
}

希望這個答案有幫助

https://stackoverflow.com/a/14107672/1060656

這是一個代碼片段,希望這有幫助

http://ss64.com/nt/cmd.html獲取 cmd.exe 幫助

private int CallShell(string exeCommand, string Parameters)
        {
            //http://ss64.com/nt/cmd.html
            /*
            This function will actually take the shell string and envoke the appropriate process
             passing it the arguments to do the work
            */

            // Initialize the process and its StartInfo properties.
            System.Diagnostics.Process ProcessEXE = new System.Diagnostics.Process();

            logger.DebugFormat("About to Start Process - {0} {1}",exeCommand, Parameters);
            try
            {

                ProcessEXE.StartInfo.FileName = exeCommand;


                // Set UseShellExecute to false for redirection.
                //  false if the process should be created directly from the executable file
                ProcessEXE.StartInfo.UseShellExecute = false;
                ProcessEXE.StartInfo.WorkingDirectory = System.Environment.CurrentDirectory;

                //EnableRaisingEvents property indicates whether the component should be notified when the operating system has shut down a process

                ProcessEXE.StartInfo.Arguments = Parameters;

                ProcessEXE.StartInfo.RedirectStandardOutput = true;
                ProcessEXE.StartInfo.RedirectStandardError = true;
                ProcessEXE.EnableRaisingEvents = true;
                ProcessEXE.StartInfo.CreateNoWindow = true;

                ProcessEXE.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(ProcessEXE_OutputDataReceived);
                ProcessEXE.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(ProcessEXE_OutputDataReceived);

                logger.DebugFormat("Process Started.");
                ProcessEXE.Start();


                // Start the asynchronous read of the sort output stream.
                ProcessEXE.BeginErrorReadLine();
                ProcessEXE.BeginOutputReadLine();

                //The WaitForExit overload is used to make the current thread wait until the associated process terminates
                logger.DebugFormat("Process Waiting for exit.");
                ProcessEXE.WaitForExit();

                if (ProcessEXE.ExitCode == 0)
                {
                    logger.Debug(string.Format("Shell Process exited with exit code {0}", ProcessEXE.ExitCode));
                }
                else
                {
                // throw error here if required - check the return error code
                    logger.Warn(string.Format("Shell Process exited with exit code {0}", ProcessEXE.ExitCode));
                }
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Method:{0}", ex.TargetSite), ex);
            }

            return ProcessEXE.ExitCode;
        }


void ProcessEXE_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
        {
            try
            {
                StringBuilder sb = new StringBuilder(string.Empty);
                if (e == null) return;

                if (e.Data == null)
                {
                    //No processing
                }
                else
                {
                   // your logic to detect error msg out from output - if at all required
                }

                if (sb.ToString().ToUpper().IndexOf("ERROR") > 0)
                {
                    string smessage = "Error text found in  output.";

                // do your error response action here .

                }
            }
            catch (Exception exp)
            {
                logger.ErrorFormat("Error in ProcessEXE_OutputDataReceived Message:{0}", exp.Message);
                logger.ErrorFormat("Error in ProcessEXE_OutputDataReceived Data Received:{0}", e.Data);

            // either throw error msg or kill the process 
            }
            finally
            {
                // Not throwing the exception
            }
        }

我當然希望您能夠控制外部應用程序的代碼,否則您會很頭疼。 最重要的事情是確保該應用程序無法掛起而不終止。

然后,您可以使用 WaitForExit()、ExitCode、StandardError、StandardOut 來“捕獲所有可能的錯誤並找出它何時完成”

您最好捕獲控制台應用程序的所有輸出並將其存儲在可以在狀態頁面上顯示的位置,而不是等待應用程序完成。

正如上面其他人所說,否則你會經歷痛苦。

你會遇到這個問題。 ASP.NET 網頁在嚴格的安全上下文下運行,甚至可能無法啟動外部進程。

此外... ASP.NET 將“一時興起”回收(停止/重新啟動其所有進程)。 這意味着網頁在任何時候都可能中止其執行。

您是否考慮過使用作業/任務調度程序? SQL Server 自帶的那個(非快遞版)很好用。

您無法從外部程序中捕獲任何錯誤。 最多您可以將其輸出重定向到您自己的流,並希望它在失敗/成功時會寫一些東西。 您還可以使用 Process.ExitCode 檢查進程退出代碼。

您可以使用 Process.Exited 事件或 Process.HasExited 屬性測試流程是否完成。

另外您應該注意,默認情況下,Asp.Net 代碼在 NETWORK SERVICE 進程(iis6 及更高版本)下運行,因此它的權限有限,登錄用戶將無法看到它的 UI。

@rbobby:您可以在 Asp.Net 代碼中啟動外部進程,但它將繼承 Asp.Net 代碼的安全上下文。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM