2012-09-21 113 views
0

我的應用程序依賴於一些DLL。我把他們都在資源和比對應用程序的開始我用我在網上找到的方法加載它們:從資源加載dll失敗

public static void LoadDllsFromResources() 
     { 
     AppDomain.CurrentDomain.AssemblyResolve += (sender, a) => 
     { 
      string dllName = a.Name.Contains(',') 
           ? a.Name.Substring(0, a.Name.IndexOf(',')) 
           : a.Name.Replace(".dll", ""); 

      dllName = dllName.Replace(".", "_"); 

      if (dllName.EndsWith("_resources")) return null; 

      System.Resources.ResourceManager rm = 
       new System.Resources.ResourceManager(
        "DesktopDashboard" + ".Properties.Resources", 
        System.Reflection.Assembly.GetExecutingAssembly()); 

      byte[] bytes = (byte[])rm.GetObject(dllName); 

      return System.Reflection.Assembly.Load(bytes); 
     }; 
    } 

它的工作對我罰款,直到我試圖添加WPFToolkitExtended.dll。比我的應用程序拋出一個錯誤。是什麼讓這個DLL如此特別?

System.Windows.Markup.XamlParseException: '設置的ConnectionId拋出 例外。'行號「4」和行位置「37」。 ---> System.InvalidCastException:[A] Xceed.Wpf.Toolkit.BusyIndi​​cator不能將 轉換爲[B] Xceed.Wpf.Toolkit.BusyIndi​​cator。在 字節數組的上下文「LoadNeither」中,類型A源自 'WPFToolkit.Extended,Version = 1.7.4644.13122,Culture = neutral, PublicKeyToken = 3e4669d2f30244f4'。類型B源於 字節數組中的上下文「LoadNeither」中的'WPFToolkit.Extended, 版本= 1.7.4644.13122,Culture = neutral, PublicKeyToken = 3e4669d2f30244f4'。在 DesktopDashboard.LogoutWindow.System.Windows.Markup.IComponentConnector.Connect(Int32 connectionId,Object target)at MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetConnectionId(Object root, Int32 connectionId,Object instance)---內部異常 堆棧跟蹤的末尾在 System.Windows.Markup.XamlReader.RewrapException(例外五, IXamlLineInfo lineInfo,烏里基本URI)在 System.Windows.Markup.WpfXamlLoader.Load(xamlReader xamlReader, IXamlObjectWriterFactory writerFactory ,布爾型 skipJournaledProperties,Object rootObject,XamlObjectWriterSettings settings,Uri baseUri)at System.Windows.Markup.WpfXamlLoa der.LoadBaml在 系統(XamlReader xamlReader, 布爾skipJournaledProperties,對象rootObject,XamlAccessLevel ACCESSLEVEL,烏里基本URI)在 System.Windows.Markup.XamlReader.LoadBaml(流流,ParserContext parserContext,父對象,布爾closeStream)。 Windows.Application.LoadComponent(對象部件,烏里 resourceLocator)處 DesktopDashboard.LogoutWindow..ctor() DesktopDashboard.LogoutWindow.InitializeComponent()在 DesktopDashboard.MainWindow.ContextMenuItemLogout_Click(對象發件人, RoutedEventArgs e)上 系統.Windows.RoutedEventHandlerInfo.InvokeHandler(對象目標, RoutedEventArgs rou tedEventArgs)處 System.Windows.UIElement.RaiseEvent System.Windows.EventRoute.InvokeHandlersImpl(對象源, RoutedEventArgs指定參數時,布爾再加註)在 System.Windows.UIElement.RaiseEventImpl(DependencyObject的發件人, RoutedEventArgs參數)(RoutedEventArgs e)上在 MS.Internal.Threading.ExceptionFilterHelper System.Windows.Controls.MenuItem.InvokeClickAfterRender(對象ARG)
在System.Windows.Threading.ExceptionWrapper.InternalRealCall(代表 回調,對象指定參數時,的Int32 numArgs)。 TryCatchWhen(Object source,Delegate method,Object args,Int32 numArgs,Delegate catchHandler)at System.Windows.Threading.DispatcherOperation.InvokeImpl()處 系統 System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(對象 狀態)在System.Threading.ExecutionContext.runTryCode(對象 用戶數據)。Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup在 System.Threading.ExecutionContext.RunInternal(TryCode 代碼,CleanupCode backoutCode,對象的UserData)(的ExecutionContext 的ExecutionContext,ContextCallback回調,對象狀態)在 System.Threading.ExecutionContext.Run(的ExecutionContext 的ExecutionContext,ContextCallback回調,對象的狀態,布爾 ignoreSyncCtx)在 System.Threading.ExecutionContext.Run(的ExecutionContext 的ExecutionContext,ContextCallback回調,對象狀態)留在 System.Windows System.Windows.Threading.DispatcherOperation.Invoke() .Threading.Dispatcher.ProcessQueue()at System.Windows.Threading.D ispatcher.WndProcHook(IntPtr的HWND,的Int32 味精,IntPtr的wParam中,IntPtr的lParam的,布爾&處理)在 MS.Win32.HwndWrapper.WndProc(IntPtr的HWND,MSG的Int32,IntPtr的wParam中,01​​IntPtr的lParam的,布爾&處理)在 MS.Win32.HwndSubclass.DispatcherCallbackOperation(對象O)在 System.Windows.Threading.ExceptionWrapper.InternalRealCall在 (代表 回調,對象指定參數時,的Int32 numArgs)MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(對象 源,代表方法,對象args,Int32 numArgs,委託 catchHandler)在 System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority pr iority,時間跨度超時,委託方法,對象在MS.Win32.HwndSubclass.SubclassWndProc(在 MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG & MSG指定參數時,的Int32 numArgs)的IntPtr HWND, 的Int32味精,IntPtr的wParam中,IntPtr的LPARAM) )在 System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame 幀)在 System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame幀)
在System.Windows.Application.RunDispatcher(對象忽略)在 系統。 Windows.Application.RunInternal(Window window)at System.Windows.Application.Run(Window window)at System.Windows.Application.Run()at DesktopDash board.App.Main(String [] args)

回答

3

您的代碼不止一次地加載了相同的程序集。當你使用Assembly.Load(byte [])時,這是一個問題,CLR無法幫助你發現程序集已經被加載。技術術語是這樣的程序集在沒有「加載上下文」的情況下被加載。接下來出現的問題是相同的類型不再兼容,類型標識不僅包含namspace名稱和類型名稱,還包含它來自的組件。

確保您在請求相同組件時確保返回完全相同的組件參考是您的工作。最好的辦法是保留一個跟蹤這種組件的Dictionary<string, Assembly>

+0

你有什麼想法,爲什麼只有這個DLL發生這種情況?我以完全相同的方式處理了其餘部分。 – gisek

+0

當多個程序集引用此Xceed工具包程序集時,會發生這種情況。當然,這對於「工具包」風格的裝配來說並不少見。如果你不想解決這個問題,那麼Setup.exe是一個明顯的解決方案。建議,工具包通常很大,你真的想要利用ngen.exe –

0

假設您使用visual studio,可以直接從IDE將它們添加到項目中。 Look here

+0

是的我正在使用VS.也許我還不夠清楚。這個應用程序工作正常,只要DLL(已添加到引用)旁邊的exe文件,但我想要它內置到我的EXE文件,並從應用程序啓動時從資源加載 - 成功與其他DLL工作。 – gisek