从ASP.NET启动外部进程

svujldwt  于 12个月前  发布在  .NET
关注(0)|答案(6)|浏览(182)

我需要从我的Web应用程序启动外部进程。这意味着使用 System.Diagnostics.ProcessStartInfo 调用并执行控制台应用程序(exe)。但我需要以某种方式 * 确保在执行过程中 * 没有出错**,并知道应用程序何时完成**工作。

捕获所有可能的错误并找出完成时间的最佳方法是什么?

2ekbmq32

2ekbmq321#

使用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; 
}

字符串

idfiyjo8

idfiyjo82#

我当然希望你能控制外部应用程序的代码,否则你会有很多麻烦。最重要的是要确保该应用程序没有办法挂起和终止。
然后,您可以使用WaitForExit(),ExitCode,StandardError,StandardOut来“捕获所有可能的错误并找出它何时完成”

i2byvkas

i2byvkas3#

你最好捕获控制台应用程序的所有输出,并将其存储在可以在状态页面上显示的地方,而不是等待应用程序完成。
正如上面的每个人所说,否则你会经历痛苦。

mqxuamgl

mqxuamgl4#

希望这个答案能有所帮助
https://stackoverflow.com/a/14107672/1060656
这里是一个代码片段,希望这对你有帮助
http://ss64.com/nt/cmd.html for xl.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
            }
        }

字符串

ih99xse1

ih99xse15#

在严格的安全上下文下运行. ASP.NET网页时,您可能会遇到问题,甚至可能无法启动外部进程。
另外,ASP.NET会“心血来潮”地循环(停止/重新启动所有进程)。这意味着在任何时候,网页都可能被中止执行。
你考虑过使用作业/任务调度器吗?SQL Server(非Express版本)附带的调度器非常好。

wlsrxk51

wlsrxk516#

你不能捕获任何来自外部程序的错误。最多你可以将其输出重定向到你自己的流,并希望它在失败/成功时会写一些东西。你也可以使用Process. ExitCode检查进程退出代码。
可以使用Process. haserted事件或Process. haserted属性测试进程是否完成。
你还应该注意到,默认情况下,Asp.NET代码运行在NETWORK SERVICE进程(iis 6及以上版本)下,因此它将具有有限的权限,登录用户将无法看到它的UI。
@rbobby:您可以在Asp.NET代码中启动外部进程,但它将继承Asp.NET代码的安全上下文。

相关问题