【问题标题】:How to detect an application executed by a Process whether the application stops working due to an invalid input?如何检测进程执行的应用程序是否由于无效输入而停止工作?
【发布时间】:2011-03-06 14:07:16
【问题描述】:

我想创建一个LaTeX 编辑器来生成pdf 文档。 在幕后,我的应用程序使用通过Process 实例执行的pdflatex.exe

pdflatex.exe 需要一个输入文件,例如input.tex 如下

\documentclass{article}
\usepackage[utf8]{inputenc}
\begin{document}
\LaTeX\ is my tool.
\end{document}

为简单起见,这里是我的LaTeX 编辑器中使用的最小c# 代码:

using System;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Process p = new Process();

            p.EnableRaisingEvents = true;
            p.Exited += new EventHandler(p_Exited);

            p.StartInfo.Arguments = "input.tex";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.FileName = "pdflatex.exe";

            p.Start();
            p.WaitForExit();
        }

        static void p_Exited(object sender, EventArgs e)
        {
            // remove all auxiliary files, excluding *.pdf.
        }
    }
}

问题是

如何检测pdflatex.exe是否因输入无效而停止工作?

编辑

这是最终的工作解决方案:

using System;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Process p = new Process();

            p.EnableRaisingEvents = true;
            p.Exited += new EventHandler(p_Exited);

            p.StartInfo.Arguments = "-interaction=nonstopmode input.tex";// Edit
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.FileName = "pdflatex.exe";
            p.StartInfo.RedirectStandardError = true;
            p.Start();
            p.WaitForExit();

            //Edit
            if (p.ExitCode == 0)
            {
                Console.WriteLine("Succeeded...");
            }
            else
            {
                Console.WriteLine("Failed...");
            }
        }

        static void p_Exited(object sender, EventArgs e)
        {
            // remove all  files excluding *.pdf

            //Edit
            Console.WriteLine("exited...");
        }
    }
}

使用-interaction=nonstopmode 的想法属于@Martin here

【问题讨论】:

    标签: c# pdflatex


    【解决方案1】:

    大多数命令行应用程序都会设置退出代码来指示成功或失败。你这样测试它:

    p.WaitForExit();
    if (p.ExitCode == 0) {
        // Success
    } else {
        // Failure
    }
    

    【讨论】:

      【解决方案2】:

      我想您可以通过查看其输出来了解pdflatex 是否停止工作(例如匹配错误消息,看到它在超过 30 秒内没有输出任何内容,诸如此类)。

      为了能够执行此类检查,您应该将pdflatex 的标准输出和标准错误(您可以通过searching in SO 找到许多示例,关键是ProcessStartInfo.RedirectStandardOutput 属性)到您的流可以读取/回调您的函数;这样你应该能够检测到你推断pdflatex被卡住的条件,然后你可以用p.Kill()杀死它。

      【讨论】:

        【解决方案3】:

        如果你有办法检测到你的进程已经停止工作,你可以使用

        p.Kill();
        

        终止进程

        一种解决方法是超时。如果你有一个单独的线程来启动这个进程,你可以启动线程并使用

                if(processThread.Join(waitTime))
                {
                    // worked
                }
                else
                {
                    // Timeout. need to kill process
                }
        

        waitTime 的类型为 TimeSpan

        【讨论】:

          【解决方案4】:

          超时更适合执行后台处理的外壳应用程序。以下代码示例为外壳应用程序设置超时。该示例的超时设置为 5 秒。您可能需要调整此数字(以毫秒计算)以进行测试:

          //Set a time-out value.
          int timeOut = 5000;
          //Start the process.
          Process p = Process.Start(someProcess);
          //Wait for window to finish loading.
          p.WaitForInputIdle();
          //Wait for the process to exit or time out.
          p.WaitForExit(timeOut);
          //Check to see if the process is still running.
          if (p.HasExited == false)
          {
              //Process is still running.
              //Test to see if the process is hung up.
              if (p.Responding)
              {
                  //Process was responding; close the main window.
                  p.CloseMainWindow();
              }
              else
              {
                  //Process was not responding; force the process to close.
                  p.Kill();
              }
          }
          //continue
          

          【讨论】:

          • IIRC Responding 属性仅对 GUI 应用程序有意义,因为它检查应用程序的主线程消息泵是否仍在处理消息(或类似的东西); pdflatex 是一个控制台应用程序,这不应该在这里应用。
          • @user596314:我为 shell 应用添加了一个示例。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-25
          • 2018-10-14
          • 1970-01-01
          • 2021-12-29
          • 2015-07-21
          相关资源
          最近更新 更多