2012-02-23 119 views
1

我有一個由其他人寫的DLL,並且有許多缺陷。我們假設在這個DLL中只定義了一個類。我需要導入這個DLL並創建這個類的一個實例。 該DLL的代碼可能如下:如何避免我們的程序因爲它動態加載的DLL而崩潰

[Serializable()] 
    public class makeExceptionClass 
    { 
     public bool isStringNormalized(string aString) 
     { 
      // A null check should be performed 
      return aString.IsNormalized(); 
     } 
    } 

我寫了一個小程序來檢查我的程序是否仍然可以運行,即使該DLL崩潰。該計劃只是一個概念證明。它有兩個參數,第一個用於從程序集直接加載DLL,第二個用於引發崩潰。 該方案的代碼如下:

class Program 
{ 
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] 
    static void Main(string[] args) 
    { 
     string typeOfLoading = args[0]; 
     string crash = args[1]; 

     // Load the DLL 
     if (typeOfLoading.Equals("direct") == true) 
     { 
      Console.WriteLine("Loading directly a DLL"); 
      Assembly anAssembly = Assembly.Load("unloadableDLL"); // Directly load the DLL 
      unloadableDLL.makeExceptionClass anObject = (unloadableDLL.makeExceptionClass)anAssembly.CreateInstance("unloadableDLL.makeExceptionClass"); 

      if (crash.Equals("crash") == true) 
      { 
       bool test = anObject.isStringNormalized(null); 
      } 
      else 
      { 
       bool test = anObject.isStringNormalized("test"); 
      } 
     } 
     else if (typeOfLoading.Equals("indirect") == true) 
     { 
      Console.WriteLine("Loading indirectly a DLL"); 
      AppDomain anAppDomain = AppDomain.CreateDomain("RemoteLoaderDomain"); // Assume it does not fail; 
      Type t = typeof(unloadableDLL.makeExceptionClass); 
      unloadableDLL.makeExceptionClass anObject = (unloadableDLL.makeExceptionClass)anAppDomain.CreateInstanceAndUnwrap("unloadableDLL", t.FullName); 

      if (crash.Equals("crash") == true) 
      { 
       bool test = anObject.isStringNormalized(null); 
      } 
      else 
      { 
       bool test = anObject.isStringNormalized("test"); 
      } 
      Console.WriteLine("Unloading the domain"); 
      AppDomain.Unload(anAppDomain);     
     } 
     else 
     { 
      // don't care 
     } 

     // terminate 
     Console.WriteLine("Press any key to exit"); 
     Console.ReadKey(); 
    } 
} 

的問題是,如果DLL被直接或進入一個AppDomain加載我的程序無論崩潰。 我對C#完全陌生(我今天早上開始),但是我有一個C++背景。在你的電話

+0

你所說的 「崩潰」 是什麼意思?例外? – BlueM 2012-02-23 18:13:55

+3

您可能會考慮查看MEF和/或MAF;這兩個框架都允許您將潛在的惡意或錯誤的第三方代碼加載到應用程序中,並通過已建立的界面與其通信。更一般地說:你正在嘗試一個本質上困難的任務,即使有經驗的C#程序員也會覺得棘手。我不會選擇C#編碼的第一天,甚至是第1000天。祝你好運! – 2012-02-23 18:21:59

+0

是的,我沒有真的選擇它,我懇請我的老闆做到這一點:D – 2012-02-24 08:32:37

回答

1

添加try/catch語句:

try 
    { 
    if (crash.Equals("crash") == true) 
    { 
     bool test = anObject.isStringNormalized(null); 
    } 
    else 
    { 
     bool test = anObject.isStringNormalized("test"); 
    } 
    } catch (Exception ex) { 
    Console.WriteLine("exception in dll call: "+ex); 
    } 
+0

嗨。那麼appDomain的目的是什麼? – 2012-02-23 19:30:11

+0

我的猜測是NullRef異常不是崩潰。你得到這個異常並且應該處理它。碰撞會被認爲是非法的,例如訪問衝突或段錯誤等非託管代碼中發生的事情。你的邏輯可以防止DLL中的代碼可以拋出異常。 – BlueM 2012-02-23 20:23:02

+0

嗨。我必須澄清這個問題:一個團隊需要通過產品的以太網測試通信。團隊使用NI TestStand編寫測試。
TestStand使用我編寫的DLL,但我沒有任何對testStand代碼的控制權。在我的DLL中,我有一個類B的成員。類型B的這個成員來自我無法控制的DLL(我們稱之爲DLLB),因爲我不負責它。
由於DLLB中的異常,TestStand崩潰。 TestStand沒有try catch異常處理,它認爲它通過我的B成員使用DLLB。 – 2012-02-23 20:58:30

相關問題