C# 当外部子进程调用错误对话框时,如何检测并作出反应
我知道,乍一看,这可能是你以前见过的一个问题: 但这略有不同 我有一个C#asp.net web应用程序,用于帮助人们为自己的程序创建安装程序。(这里的开发人员大多是机械工程师,在某些计算工具中编写公式,他们不是软件人员,因此我们不希望他们花时间学习wix、调试安装程序、在不同版本之间维护GUID等等。) 服务器端将运行控制台应用程序“heat.exe”(wix工具附带的一个工具),以获取有关如何注册dll等的信息,前提是且仅当它们的存储库中有dll 我是这样做的:C# 当外部子进程调用错误对话框时,如何检测并作出反应,c#,wix,runtime-error,C#,Wix,Runtime Error,我知道,乍一看,这可能是你以前见过的一个问题: 但这略有不同 我有一个C#asp.net web应用程序,用于帮助人们为自己的程序创建安装程序。(这里的开发人员大多是机械工程师,在某些计算工具中编写公式,他们不是软件人员,因此我们不希望他们花时间学习wix、调试安装程序、在不同版本之间维护GUID等等。) 服务器端将运行控制台应用程序“heat.exe”(wix工具附带的一个工具),以获取有关如何注册dll等的信息,前提是且仅当它们的存储库中有dll 我是这样做的: public in
public int runHeat(string filePath, string outputFile, ref string response)
{
response += "run heat.exe to harvest file data" + '\r' + '\n';
string args = "file " + '"' + filePath + '"' + " -srd -out" + '"' + outputFile + '"';
string command = Path.Combine(WixBinariesPath, "heat.exe");
string workPath = Path.GetDirectoryName(filePath);
StringBuilder outputBuilder;
ProcessStartInfo processStartInfo;
Process process;
outputBuilder = new StringBuilder();
processStartInfo = new ProcessStartInfo();
processStartInfo.CreateNoWindow = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.UseShellExecute = false;
processStartInfo.WorkingDirectory = workPath;
processStartInfo.Arguments = args;
processStartInfo.FileName = command;
processStartInfo.ErrorDialog = false;
//create the process handler
process = new Process();
process.StartInfo = processStartInfo;
// enable raising events because Process does not raise events by default
process.EnableRaisingEvents = true;
// attach the event handler for OutputDataReceived before starting the process
process.OutputDataReceived += new DataReceivedEventHandler
(
delegate(object sender, DataReceivedEventArgs e)
{
// append the new data to the data already read-in
outputBuilder.AppendLine(e.Data);
}
);
// start the process
// then begin asynchronously reading the output
// then wait for the process to exit
// then cancel asynchronously reading the output
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
// use the output
response += outputBuilder.ToString();
if (process.ExitCode != 0)
response += '\r' + '\n' + "heat.exe exited with code: " + process.ExitCode;
process.CancelOutputRead();
return process.ExitCode;
}
我认为这很有效。。
它通过了测试,已经运行了一段时间没有出现问题,然后突然,一位开发人员打电话说,我制作的webtool不再为他生成WIXXML
当我登录到服务器时,我发现以下对话框:
然后单击[OK]——然后web应用程序继续运行,并生成xml,这些东西都起作用了
我现在已经找到了使heat抛出此错误的dll。它实际上不需要注册(典型的对吧?)。所以我可能只需要写一个超时的东西,如果需要很长的时间,就杀死heat.exe,从而解锁等待的脚本(基本上解决这个问题,直到它再次发生,使用一个实际需要注册的dll),但这并不是真的检测错误,只是检测这些东西需要时间
对于此错误,我希望继续脚本,但向用户发出警告,heat.exe无法在该特定文件上运行。但要做到这一点,我需要我的asp.net应用程序知道调用了此错误,并对其进行处理,以便脚本可以继续
你觉得怎么样?我是否获得发生此运行时错误的信息,以便可以从服务器脚本中处理它
您是否尝试过使用-sreg命令行选项来加热 我现在拥有了heat.exe,因此它不再是chrash,但这不是一个解决方案,因为heat还可以避免获取自动注册所述代码附带的dll所需的注册表信息。使用外部“不合作”可执行文件通常需要一些技巧。我会尝试以下方法:
- 在命令行上启动程序,并检查出现错误时是否有任何输出。可能它写入标准错误,您可以使用重定向标准错误,读取流,并希望在错误发生时获得线索
- 检查heat.exe中是否有任何可以启用的日志记录,并使用它来检测错误情况。可能是详细设置或日志文件
- 如果以上都不起作用,我会使用过程监视器(例如)。启动process monitor,然后启动应用程序,并将其带到错误点。在ProcessMonitor中过滤巨大的输出,只针对您的应用程序(仍然很多),并在最后搜索是否存在程序可能记录错误的访问。可能是一些日志文件,或者是日志服务。您可以在超时后检查此文件
- 但无论如何,你在问题中已经提出的黑客方法都会奏效。检测对话框是否打开。还可以浏览对话框的内容,因此您还可以阅读文本并检查它是哪种错误。我在生产代码中使用了一次,以获取外部程序的进度,该程序编写在表单中的文本字段中。我使用spy++(与Visual Studio捆绑)获取文本字段的名称/id,并使用(本机)windows API访问它。一个丑陋的黑客,但工作良好,除非外部程序的用户界面改变。 在您的情况下,它是一个标准错误对话框,因此应该保持一致