如何检测进程执行的应用程序是否由于输入无效而导致应用程序停止工作?
我想创建一个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。
大多数命令行应用程序设置退出代码以指示成功或失败。 你这样测试它:
p.WaitForExit(); if (p.ExitCode == 0) { // Success } else { // Failure }
我想你可以通过查看输出来了解pdflatex
是否已停止工作(例如,匹配错误消息,看到它输出的内容超过30秒,就像这样)。
为了能够执行此类检查,您应该将pdflatex
的标准输出和标准错误(您可以通过搜索SO ,关键是ProcessStartInfo.RedirectStandardOutput
属性找到很多示例)重定向到您可以读取的流/回调你的function; 通过这种方式,你应该能够检测出推断pdflatex
被卡住的条件,然后你可以用p.Kill()
来杀死它。
如果您有办法检测您的进程已停止工作,则可以使用
p.Kill();
终止进程
一种方法是暂停。 如果您有一个单独的线程来启动此过程,您可以启动该线程并使用
if(processThread.Join(waitTime)) { // worked } else { // Timeout. need to kill process }
其中waitTime的类型为TimeSpan
超时更适合执行后台处理的shell应用程序。 以下代码示例为shell应用程序设置超时。 示例的超时设置为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