【问题标题】:WinForms: there is no disk in the drive. please insert a disk into driveWinForms:驱动器中没有磁盘。请在驱动器中插入磁盘
【发布时间】:2011-04-26 21:01:32
【问题描述】:

我有一个 WinForms 应用程序。它被写入磁盘。我从磁盘运行应用程序并从 CD 中弹出磁盘。然后我接受了例外:驱动器中没有磁盘。请在驱动器中插入磁盘。如何捕获此异常并正确关闭我的应用程序?

【问题讨论】:

  • “正确关闭我的应用程序”是什么意思?您只是想捕获异常,还是想执行清理操作?
  • 我想捕获这个异常并自行替换它的消息(然后可能是关闭应用程序)。

标签: c# .net winforms exception


【解决方案1】:

您可以像这样修改您的 Program.cs:

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        try
        {
            Application.Run(new Form1());
        }
        catch (Exception ex)
        {
            // Display the exception to the end user.
        }
        finally
        {
            // Do your cleanup here.
        }
    }

这应该会捕获应用程序本身无法捕获的所有异常。

【讨论】:

  • 使用 finally 而不是 catch 块。无论系统和线程异常如何,都会命中 finally 块。
【解决方案2】:

您应该尝试检测 cd 弹出。这是一个工作示例:publicjoe.f9.co.uk/csharp/snip/snip002.html

你也可以看看这个: Detecting Eject/Insert of Removeable Media

【讨论】:

  • Application.ThreadException 没有捕捉到这个异常。出现消息,但未调用 Application_ThreadException。
  • 您是否也添加了 UnhandledException 处理程序?如果您处理它,此消息将不会自行显示。
  • 我尝试添加 AppDomain.CurrentDomain.UnhandledException。它也没有捕捉到这个异常。
  • 编辑了答案,添加了 SetUnhandledExceptionMode。也可以考虑检测cd弹出。
  • 同样的问题。我收到错误消息,无法通过 X 按钮关闭应用程序。但现在我在 .._Exception 方法中有一些例外。但它只出现在不需要的 MessageBox 之后。
【解决方案3】:

这是任何类型程序的一般问题,并非特定于 Winforms 应用程序。它与创建流程的方式有关。 Windows 创建一个所谓的内存映射文件,它将文件中的字节映射到进程的地址空间。这是从文件中读取数据的一种非常有效的方法,只有在实际需要数据时才会进行磁盘读取。当程序执行跳转到特定的代码块,或者 JIT 编译器需要 IL 用于方法时,当数据还没有被读取时就会产生页面错误。操作系统通过从文件中读取一个块来解决它。您只需为实际运行的代码付费。

另一个主要好处是当系统处于压力之下并且需要太多 RAM 来保持进程运行时。内存管理器从 RAM 中取出页面,为需要 CPU 的进程腾出空间。这些页面通常被写入页面文件。但是当它们来自 EXE 文件时,这是不必要的。它可以简单地丢弃它们,并始终通过重新读取文件来取回它们。

您可能会看到这会导致什么:当您弹出磁盘时,无法从 EXE 文件加载页面。 Windows 注意到这一点并弹出对话框。这是一个非常低级的错误处理机制,你不能在进程本身中捕获它。那是行不通的,因为这需要在你的程序中执行代码。无法再从磁盘加载的代码。

您可以通过调用 SetErrorMode() 来抑制错误。不确定,没试过。但这并不能真正解决任何问题,可能发生的下一个最好的事情是 Windows 以一个模糊的错误终止程序。唯一合理的解决方案是让用户按照 Windows 的要求放回磁盘,或者从您的媒体运行安装程序,以便在硬盘驱动器上创建程序的副本。

【讨论】:

    【解决方案4】:

    使用EDITBIN /SWAPRUN 告诉Windows 您的可执行文件驻留在可移动设备上。它会在运行前将其复制到交换文件中。

    这是您通常为(例如)安装程序所做的事情。如果您依赖其他 DLL,我不确定这是否有效,但我认为可以。

    对于其他资源,您希望在初始化期间尽快将它们复制到临时位置。

    或者,您可以调用 SetErrorMode 来禁用消息框并正确处理错误。

    【讨论】:

    • 谢谢!这是一个非常有趣的想法,但我的应用程序有很多外部资源。无论如何我都应该关闭程序。
    • 很公平。更新了更多细节,以防其他人觉得这很有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-27
    • 2014-12-01
    • 2012-08-10
    相关资源
    最近更新 更多