如何在外部子进程调用错误对话框时检测并做出反应

Hen*_*rik 6 c# runtime-error wix

我知道这可能乍一看看起来像你之前看到过的一个问题: 知道外部进程的窗口何时显示

但这有点不同.

我有一个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;
    }
Run Code Online (Sandbox Code Playgroud)

我认为这很有效..它通过测试,它已经运行了一段时间没有问题,然后突然,一个开发人员打电话,我做的webtool,不再为他生成wix xml ..

当我登录服务器时,我找到了这个对话框:

运行时错误消息

然后单击[确定] - Web应用程序然后继续,并生成xml,并且工作正常...

我现在已经找到了这个dll,让热量抛出这个错误.它真的不需要注册(典型的权利?).所以我可能只是写一个超时的东西,如果需要很长时间来杀死heat.exe,从而解锁等待的脚本,(并且基本上解决问题,直到它再次发生,实际上需要注册的dll)但是这不是真正检测到错误,就是检测到这些东西需要时间......

在此错误上,我想继续该脚本,但向用户发出警告,即heat.exe无法在该特定文件上运行.但要做到这一点,我需要我的asp.net应用程序知道这个错误被调用,并处置它,以便脚本可以继续..

如何*?获取有关此运行时错误的信息,以便我可以从服务器脚本处理它?

您是否尝试使用-sreg命令行选项加热?

我现在有了,因此,heat.exe不再崩溃,但这不是一个解决方案,因为热量也避免了收集我需要的注册表信息,以便自动注册有问题的代码附带的dll.

azt*_*azt 1

使用外部“不合作”可执行文件通常需要一些技巧。我会尝试以下操作:

  • 在命令行启动程序,出现错误时查看是否有输出。它可能会写入标准错误,您可以使用 RedirectStandardError,读取流并希望在错误发生时获得线索。

  • 检查 heat.exe 中是否有任何可以启用的日志记录功能,并使用它来检测错误情况。也许是一个详细的设置,或者一个日志文件......

  • 如果上述方法都不起作用,我会使用进程监视器(例如https://technet.microsoft.com/de-at/sysinternals/bb896645.aspx)。启动进程监视器,然后启动您的应用程序,并将其带到错误点。将进程监视器中的大量输出过滤到您的应用程序(仍然相当多),并在最后搜索是否存在程序可能记录错误的任何访问。也许是一些日志文件,或者日志服务。您可以在超时后检查此文件。

  • 但无论如何,您在问题中已经建议的技巧都是可行的。检测对话框是否打开。还可以浏览对话框的内容,因此您还可以阅读文本并检查它是哪种错误。我在生产代码中使用过一次它来获取外部程序的进度,该程序写在表单内的文本字段中。我使用spy++(与 Visual Studio 捆绑在一起)来获取文本字段的名称/ID,并使用(本机)Windows API 访问它。这是一个丑陋的黑客行为,但除非改变外部程序的用户界面,否则工作正常。在您的情况下,它是一个标准的错误对话框,因此它应该保持相当一致。