How to detect an application executed by a Process whether the application stops working due to an invalid input?

大城市里の小女人 提交于 2019-12-08 03:24:05

问题


I want to create a LaTeX editor to produce pdf documents. Behind the scene, my application uses pdflatex.exe executed through a Process instance.

pdflatex.exe needs an input file, e.g., input.tex as follows

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

For the sake of simplicity, here is the minimal c# codes used in my LaTeX editor:

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.
        }
    }
}

The question is

How to detect the pdflatex.exe whether it stops working due to an invalid input?

Edit

This is the final working solution:

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...");
        }
    }
}

The idea using -interaction=nonstopmode belongs to @Martin here.


回答1:


Most command-line applications set an exit code to indicate success or failure. You test it thus:

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



回答2:


I suppose that you can understand if pdflatex has stopped working by looking at its output (e.g. matching an error message, seeing that it doesn't output anything for more than 30 seconds, something like that).

To be able to perform such checks, you should redirect the standard output and standard error of pdflatex (you can find many examples just by searching in SO, the key is the ProcessStartInfo.RedirectStandardOutput property) to a stream that you can read/a callback to a function of yours; in this way you should be able to detect the condition whence you deduce that pdflatex is stuck, and then you can kill it with p.Kill().




回答3:


If you have a means to detect your process has stopped working, you can use

p.Kill();

to terminate the process

One way to go about it is a timeout. If you have a separate thread to launch this proces, you can start the thread and use

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

where waitTime is of type TimeSpan




回答4:


Time-outs are better suited for a shelled application that performs background processing. The following code sample sets a time-out for the shelled application. The time-out for the example is set to 5 seconds. You may want to adjust this number (which is calculated in milliseconds) for your testing:

//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


来源:https://stackoverflow.com/questions/5210950/how-to-detect-an-application-executed-by-a-process-whether-the-application-stops

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!