我知道这可能乍一看看起来像你之前看过的一个问题: Knowing when an external process' window shows
但这略有不同。
我有一个C#asp.net Web应用程序,用于帮助人们为他们的程序创建安装程序。 (这里的开发人员主要是机械工程师在某些计算工具中编写方程式,他们不是软件人员,因此我们不希望他们花时间学习wix,调试安装程序,维护发布之间的GUID等等..)
服务器端将运行控制台应用程序" heat.exe" (与wix工具一起提供的工具),以获取有关如何注册dll等的信息,当且仅当他们的存储库中有dll时...
我这样做:
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,不再为他生成wix xml ..
当我登录服务器时,我找到了此对话框:
然后单击[确定] - Web应用程序然后继续,并生成xml,并且工作正常...
我现在已经找到了这个dll,让热量抛出这个错误。它真的不需要注册(典型的权利?)。所以我可能只是写一个超时的东西,如果它需要很长时间来杀死heat.exe,从而解锁等待的脚本,(并且基本上解决问题,直到它再次发生,实际上需要注册的dll)但是这不是真正检测到错误,就是检测到这些东西需要时间......
在此错误上,我想继续该脚本,但向用户发出警告,表示heat.exe无法在该特定文件上运行。但要做到这一点,我需要我的asp.net应用程序知道这个错误被调用,并处置它,以便脚本可以继续..
如何*?我是否收到有关此运行时错误的信息,以便我可以从服务器脚本处理它?</ p>
您是否尝试使用-sreg命令行选项加热?
我现在有了,因此,heat.exe不再崩溃,但这不是一个解决方案,因为热量也避免了收集我需要的注册表信息,以便自动注册代码附带的dll。问题
答案 0 :(得分:1)
使用外部&#34;不合作&#34;可执行文件通常需要一些技巧。我尝试以下方法:
在命令行上启动程序,检查错误发生时是否有任何输出。可能它会写入标准错误,您可以使用RedirectStandardError,读取流并希望在发生错误时获得线索。
检查您可以启用的heat.exe中是否存在任何日志记录可能性,并使用此方法检测错误情况。也许是一个冗长的设置,或者是一个日志文件......
如果上述方法都不奏效,我会使用流程监控器(例如https://technet.microsoft.com/de-at/sysinternals/bb896645.aspx)。启动进程监视器,然后启动应用程序并将其置于错误点。将进程监视器中的巨大输出过滤到您的应用程序(仍然非常多)并最后搜索,是否有任何访问程序可能记录错误的位置。也许是一些日志文件或日志服务。您可以在超时后检查此文件。
但无论如何,在你的问题中你已经提出过的黑客行为。检测对话框是否打开。还可以浏览对话框的内容,因此您还可以阅读文本并检查它是哪种错误。我在生产代码中使用过一次来获取外部程序的进度,该程序是在表单内的文本字段中编写的。我使用spy ++(与Visual Studio捆绑在一起)获取文本字段的名称/ id,并使用(本机)Windows API访问它。一个丑陋的黑客,但除非外部程序的UI被更改,否则工作正常。 在你的情况下,它是一个标准的错误对话框,所以它应该保持一致。