如何检测并在外部子流程调用错误对话框时做出反应
how to detect, and react when an External sub Process, invokes an error dialog
我知道乍一看这可能像您以前见过的问题:
Knowing when an external process' window shows
但这略有不同。
我有一个 C# asp.net 网络应用程序,用于帮助人们为他们的程序创建安装程序。 (这里的开发人员大多是机械工程师,他们在一些计算工具中编写方程式脚本,他们不是软件人员,所以我们不希望他们花时间学习 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;
}
我认为这有效..
它通过了测试,已经 运行ning 了一段时间没有问题,然后突然,一个开发人员打电话给我,说我制作的 webtool 不再为他生成 wix xml..
当我登录服务器时,我发现这个对话框:
然后单击 [确定] - 然后 Web 应用程序继续,并生成 xml,一切正常..
我现在找到了使热量抛出此错误的 dll。它并不真的需要注册(典型的权利?)。所以我可能只写一个超时的东西,如果它需要很长时间就杀死 heat.exe ,从而解锁等待的脚本,(并基本上解决这个问题,直到它再次发生一个实际需要注册的dll)但是并没有真正检测到错误,只是检测到这些东西需要时间...
出现此错误时,我想继续脚本,但向用户发出警告,即 heat.exe 未能在该特定文件上 运行。但是要做到这一点,我需要我的 asp.net 应用程序知道调用了这个错误并处理它,以便脚本可以继续..
怎么了*?我如何获得发生此 运行 时间错误的信息,以便我可以从服务器脚本处理它?
Have you tried using the -sreg command line option to heat?
我现在有,因此,heat.exe 不再崩溃,但这不是解决方案,因为 heat 还避免收集我需要的注册表信息,而我需要这些信息来自动注册代码中附带的 dll问题。
使用外部 "uncooperative" 可执行文件通常需要一些技巧。我会尝试以下操作:
在命令行启动程序,出现错误时查看是否有输出。可能它会写入标准错误,您可以使用 RedirectStandardError,读取流并希望在发生错误时获得线索。
检查 heat.exe 中是否有任何您可以启用的日志记录可能性,并使用它来检测错误情况。也许是一个冗长的设置,或者一个日志文件...
如果上面的 none 有效,我会使用进程监视器(例如 https://technet.microsoft.com/de-at/sysinternals/bb896645.aspx)。启动进程监视器,然后启动您的应用程序并将其带到错误点。将进程监视器中的大量输出过滤到您的应用程序(仍然很多)并在最后搜索,是否存在程序可能记录错误的任何访问权限。也许是一些日志文件或日志记录服务。您可以在超时后检查此文件。
但是在任何情况下都会起作用的是您已经在问题中提出的 hack。检测对话框是否打开。还可以浏览对话框的内容,因此您也可以阅读文本并检查它是哪种错误。我曾经在生产代码中使用过它来获取外部程序的进度,该程序写在表单内的文本字段中。我使用 spy++(与 Visual Studio 绑定)获取文本字段的 name/id,并使用(本地)windows API 访问它。一个丑陋的 hack,但除非更改外部程序的 UI,否则工作正常。
在你的情况下,它是一个标准的错误对话框,所以它应该保持一致。
我知道乍一看这可能像您以前见过的问题: Knowing when an external process' window shows
但这略有不同。
我有一个 C# asp.net 网络应用程序,用于帮助人们为他们的程序创建安装程序。 (这里的开发人员大多是机械工程师,他们在一些计算工具中编写方程式脚本,他们不是软件人员,所以我们不希望他们花时间学习 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;
}
我认为这有效.. 它通过了测试,已经 运行ning 了一段时间没有问题,然后突然,一个开发人员打电话给我,说我制作的 webtool 不再为他生成 wix xml..
当我登录服务器时,我发现这个对话框:
然后单击 [确定] - 然后 Web 应用程序继续,并生成 xml,一切正常..
我现在找到了使热量抛出此错误的 dll。它并不真的需要注册(典型的权利?)。所以我可能只写一个超时的东西,如果它需要很长时间就杀死 heat.exe ,从而解锁等待的脚本,(并基本上解决这个问题,直到它再次发生一个实际需要注册的dll)但是并没有真正检测到错误,只是检测到这些东西需要时间...
出现此错误时,我想继续脚本,但向用户发出警告,即 heat.exe 未能在该特定文件上 运行。但是要做到这一点,我需要我的 asp.net 应用程序知道调用了这个错误并处理它,以便脚本可以继续..
怎么了*?我如何获得发生此 运行 时间错误的信息,以便我可以从服务器脚本处理它?
Have you tried using the -sreg command line option to heat?
我现在有,因此,heat.exe 不再崩溃,但这不是解决方案,因为 heat 还避免收集我需要的注册表信息,而我需要这些信息来自动注册代码中附带的 dll问题。
使用外部 "uncooperative" 可执行文件通常需要一些技巧。我会尝试以下操作:
在命令行启动程序,出现错误时查看是否有输出。可能它会写入标准错误,您可以使用 RedirectStandardError,读取流并希望在发生错误时获得线索。
检查 heat.exe 中是否有任何您可以启用的日志记录可能性,并使用它来检测错误情况。也许是一个冗长的设置,或者一个日志文件...
如果上面的 none 有效,我会使用进程监视器(例如 https://technet.microsoft.com/de-at/sysinternals/bb896645.aspx)。启动进程监视器,然后启动您的应用程序并将其带到错误点。将进程监视器中的大量输出过滤到您的应用程序(仍然很多)并在最后搜索,是否存在程序可能记录错误的任何访问权限。也许是一些日志文件或日志记录服务。您可以在超时后检查此文件。
但是在任何情况下都会起作用的是您已经在问题中提出的 hack。检测对话框是否打开。还可以浏览对话框的内容,因此您也可以阅读文本并检查它是哪种错误。我曾经在生产代码中使用过它来获取外部程序的进度,该程序写在表单内的文本字段中。我使用 spy++(与 Visual Studio 绑定)获取文本字段的 name/id,并使用(本地)windows API 访问它。一个丑陋的 hack,但除非更改外部程序的 UI,否则工作正常。 在你的情况下,它是一个标准的错误对话框,所以它应该保持一致。