问题
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