【问题标题】:Prevent app from crashing without giving info when dll is missing防止应用程序在缺少 dll 时在不提供信息的情况下崩溃
【发布时间】:2012-11-21 13:15:30
【问题描述】:

如果我的 VB.NET 程序所需的某些 dll 丢失,当我运行它时,它会崩溃并显示典型的 Windows 错误消息,并且不提供有关错误的任何信息。

所以,我想在做任何事情之前验证所有依赖项都得到满足。但这并不是微不足道的,因为我有非托管和运行时依赖项。那么,在深入研究之前,是否有一些 CLR 设置,或者针对此问题的一些更简单的解决方案?

【问题讨论】:

  • 如果您不知道您有哪些运行时依赖项,那么您可以随时从 SysInternals 的 ProcMon 实用程序中找到。您将看到您的程序正在搜索 DLL。
  • 是的。但我也有使用 /clr 开关构建的 C++/CLI 程序集,它引用非托管 C++ 程序集。不知道如何处理这些。我的意思是,我知道哪个程序集引用了哪个程序集,它以通用的方式验证它们的存在,而无需对整个依赖关系树进行硬编码。
  • 对,这就是 ProcMon 将向您展示的内容。在不到 2 分钟的时间内完成此操作是不可能的,您实际上必须尝试一下。没人能猜到你会看到什么。如果您需要更好的建议,请向您使用的 DLL 的所有者寻求帮助。他们总是有可用的部署说明。
  • 即使我知道我的程序需要哪些 dll,它仍然会在丢失时崩溃而不提供信息。这看起来很恶心。我想显示一个消息框,上面写着“XXX.dll 丢失。重新安装应用程序可能会解决问题”。我见过很多程序这样做。

标签: .net windows vb.net assembly-resolution


【解决方案1】:

这真的很简单(即避免了 Windows 的样板消息)。您只需让您的应用程序处理UnhandledException 事件。

对于像我这样的 VB.NET 应用程序窗口窗体,这意味着转到项目属性 Application 选项卡并单击 View Application events 按钮。

打开(默认隐藏)ApplicationEvents.vb 文件。我添加了一些代码:

Namespace My

    ' The following events are available for MyApplication:
    ' 
    ' Startup: Raised when the application starts, before the startup form is created.
    ' Shutdown: Raised after all application forms are closed.  This event is not raised if the application terminates abnormally.
    ' UnhandledException: Raised if the application encounters an unhandled exception.
    ' StartupNextInstance: Raised when launching a single-instance application and the application is already active. 
    ' NetworkAvailabilityChanged: Raised when the network connection is connected or disconnected.
    Partial Friend Class MyApplication

        Private Sub MyApplication_UnhandledException(ByVal sender As Object, _
                                                     ByVal e As Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs _
                                                     ) Handles Me.UnhandledException
            MessageBox.Show("Application crashed due to the following unhandled exception. " + e.Exception.ToString())
        End Sub

    End Class    

End Namespace

现在,如果我缺少某些 dll,我会在异常消息中获得它的名称(如果它是托管的还是混合的)。如果丢失的 dll 是非托管的,我只会得到需要它的混合程序集的名称。但这对我来说没关系;将混合程序集扔到 Depends.exe 上会很快发现有问题的非托管程序集。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-19
    • 2017-10-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多