2010-10-18 100 views
2

我有一個WinForms應用程序。它被寫入磁盤。我從磁盤運行應用程序並從CD中彈出磁盤。然後我排除:驅動器中沒有磁盤。請將磁盤插入驅動器。我如何捕獲這個異常並正確關閉我的應用程序?WinForms:驅動器中沒有磁盤。請將磁盤插入驅動器

+0

你是什麼意思「正確關閉我的應用程序」?你只是想抓住例外,或者你想執行清理行動? – 2010-10-18 10:46:07

+0

我想要捕獲這個異常並將其替換爲自己的消息(然後可能是關閉應用程序)。 – Rover 2010-10-18 11:19:29

回答

4

您應該嘗試檢測光盤彈出。這裏是工作示例:publicjoe.f9.co.uk/csharp/snip/snip002.html

你也可以看看這個: Detecting Eject/Insert of Removeable Media

+0

Application.ThreadException不會捕獲此異常。該消息出現,但Application_ThreadException不會被調用。 – Rover 2010-10-18 11:13:48

+0

您是否也添加了UnhandledException處理程序?如果你處理它,這個消息不會顯示。 – honibis 2010-10-18 11:22:32

+0

我試圖添加AppDomain.CurrentDomain.UnhandledException。它也沒有捕捉到這個例外。 – Rover 2010-10-18 11:32:44

0

您可以修改您的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. 
     } 
    } 

這應該捕獲所有異常你沒有趕上,否則在應用程序本身。

+1

它實際上不會捕獲系統和線程異常。 – honibis 2010-10-18 10:56:35

+0

使用終止而不是catch塊。無論系統和線程異常如何,塊最終都會被命中。 – Femaref 2010-10-18 10:59:12

+0

你是對的;更新的答案。 – 2010-10-18 11:01:40

3

這是一個通用的問題,任何種類的程序,不特定於Winforms應用程序。它與創建過程的方式有關。 Windows創建一個所謂的內存映射文件,它將文件中的字節映射到進程的地址空間。這是從文件中讀取數據的一種非常有效的方式,只有在實際需要數據時纔會發生磁盤讀取。當程序執行跳轉到特定的代碼塊時,或者JIT編譯器需要一個方法的IL時,當數據尚未讀取時會產生頁面錯誤。操作系統通過從文件中讀取塊來解決它。您只需支付實際運行的代碼。

另一個主要優勢是當系統處於壓力之下並且需要太多內存來保持進程運行時。內存管理器將頁面從內存中抽出來爲需要CPU的進程騰出空間。這些頁面通常寫入分頁文件。但是當它們來自EXE文件時,這是不必要的。它可以簡單地丟棄它們,並通過重新讀取文件來重新獲取它們。

您可能會看到這會導致:當您彈出磁盤時,從EXE文件加載頁面無法工作了。 Windows注意到這一點,並提出對話框。這是一個非常低級別的錯誤處理機制,您不能將其陷入進程本身。這是行不通的,因爲那需要在程序中執行代碼。無法從磁盤加載的代碼。

您可能可以通過禁止SetErrorMode()來抑制錯誤。不知道,從來沒有嘗試過。但是這並沒有真正解決任何問題,所以可能發生的下一個最好的事情是Windows終止程序時會出現一個模糊的錯誤。唯一合理的解決方案是讓用戶按照Windows的要求放回磁盤,或者從媒體運行安裝程序,以便在硬盤上創建該程序的副本。

2

使用EDITBIN /SWAPRUN告訴Windows您的可執行文件駐留在可移動設備上。它會在運行之前將其複製到交換文件。

這是您通常爲(例如)安裝程序所做的。我不確定這是否可以工作,如果你依賴於其他的DLL,但我認爲它可以。

對於其他資源,您希望在初始化期間儘快將它們複製到臨時位置。

或者,您可以調用SetErrorMode來禁用消息框並正確處理錯誤。

+0

謝謝!這是一個非常有趣的想法,但我的應用程序有很多外部資源。無論如何,我應該關閉該程序。 – Rover 2010-10-19 11:06:30

+0

夠公平的。更新一些更詳細的信息,以防其他人認爲有用。 – 2010-10-19 12:35:16

相關問題