【问题标题】:Loading dll from resources fails从资源加载 dll 失败
【发布时间】:2012-09-13 20:23:41
【问题描述】:

我的应用程序依赖于几个 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: 'Set connectionId throw an 例外。'行号“4”和行位置“37”。 ---> System.InvalidCastException:[A]Xceed.Wpf.Toolkit.BusyIndi​​cator 不能 被强制转换为 [B]Xceed.Wpf.Toolkit.BusyIndi​​cator。 A型起源于 'WPFToolkit.Extended,版本=1.7.4644.13122,文化=中性, PublicKeyToken=3e4669d2f30244f4' 在上下文 'LoadNeither' 中 字节数组。 B 型源自 'WPFToolkit.Extended, 版本=1.7.4644.13122,文化=中性, PublicKeyToken=3e4669d2f30244f4' 在上下文 'LoadNeither' 中 字节数组。在 DesktopDashboard.LogoutWindow.System.Windows.Markup.IComponentConnector.Connect(Int32 connectionId,对象目标)在 MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetConnectionId(对象根, Int32 connectionId, Object instance) --- 内部异常结束 堆栈跟踪 --- 在 System.Windows.Markup.XamlReader.RewrapException(异常 e, IXamlLineInfo lineInfo, Uri baseUri) 在 System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory,布尔值 skipJournaledProperties、对象 rootObject、XamlObjectWriterSettings 设置,Uri baseUri)在 System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, 布尔型 skipJournaledProperties、对象 rootObject、XamlAccessLevel accessLevel, Uri baseUri) 在 System.Windows.Markup.XamlReader.LoadBaml(流流,ParserContext parserContext, Object parent, Boolean closeStream) at System.Windows.Application.LoadComponent(对象组件,Uri 资源定位器)在 DesktopDashboard.LogoutWindow.InitializeComponent() 在 DesktopDashboard.LogoutWindow..ctor() 在 DesktopDashboard.MainWindow.ContextMenuItemLogout_Click(对象发送者, RoutedEventArgs e) 在 System.Windows.RoutedEventHandlerInfo.InvokeHandler(对象目标, RoutedEventArgs routedEventArgs) 在 System.Windows.EventRoute.InvokeHandlersImpl(对象源, RoutedEventArgs 参数,布尔 reRaised)在 System.Windows.UIElement.RaiseEventImpl(DependencyObject 发送者, RoutedEventArgs 参数)在 System.Windows.UIElement.RaiseEvent(RoutedEventArgs e) 在 System.Windows.Controls.MenuItem.InvokeClickAfterRender(对象 arg)
在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托 回调,对象参数,Int32 numArgs)在 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(对象 源,委托方法,对象参数,Int32 numArgs,委托 catchHandler) 在 System.Windows.Threading.DispatcherOperation.InvokeImpl() 在 System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(对象 状态)在 System.Threading.ExecutionContext.runTryCode(对象 用户数据)在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode 代码,CleanupCode backoutCode,对象 userData)在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext、ContextCallback 回调、对象状态)在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback 回调、对象状态、布尔值 ignoreSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback 回调、对象状态)在 System.Windows.Threading.DispatcherOperation.Invoke() 在 System.Windows.Threading.Dispatcher.ProcessQueue() 在 System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd,Int32 味精,IntPtr wParam,IntPtr lParam,布尔值&处理)在 MS.Win32.HwndWrapper.WndProc(IntPtr hwnd,Int32 msg,IntPtr wParam, IntPtr lParam,布尔值&处理)在 MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) 在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托 回调,对象参数,Int32 numArgs)在 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(对象 源,委托方法,对象参数,Int32 numArgs,委托 catchHandler) 在 System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority 优先级、TimeSpan 超时、委托方法、对象参数、Int32 numArgs) 在 MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 消息,IntPtr wParam,IntPtr lParam)在 MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) 在 System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame 帧)在 System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame 框架)
在 System.Windows.Application.RunDispatcher(对象忽略) System.Windows.Application.RunInternal(窗口窗口)在 System.Windows.Application.Run(窗口窗口)在 System.Windows.Application.Run() 在 DesktopDashboard.App.Main(String[] args)

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    您的代码多次加载同一个程序集。当您使用 Assembly.Load(byte[]) 时,这是一个问题,CLR 无法帮助您确定程序集是否已加载。技术术语是这样的程序集是在没有“加载上下文”的情况下加载的。接下来的问题是相同类型不再兼容,类型标识不仅包括命名空间名称和类型名称,还包括它来自的程序集。

    您的工作是确保在请求相同的程序集时返回完全相同的程序集引用。最好的办法是保持Dictionary<string, Assembly> 跟踪此类程序集。

    【讨论】:

    • 你知道为什么这只发生在这个 dll 上吗?我以完全相同的方式处理其余部分。
    • 当多个程序集引用此 Xceed 工具包程序集时,就会发生这种情况。当然,对于“工具包”样式的程序集来说并不少见。如果您不想解决问题,那么 Setup.exe 是显而易见的解决方案。可取的,工具包通常很大,你真的想利用 ngen.exe
    【解决方案2】:

    假设您使用的是 Visual Studio,您可以直接从 IDE 将它们添加到项目中。 Look here.

    【讨论】:

    • 是的,我正在使用 VS。也许我不够清楚。只要 dll(已添加到引用中)位于 exe 文件旁边,此应用程序就可以正常工作,但我希望将其内置到我的 exe 文件中,并在应用程序启动时从资源中加载它 - 这与其他 dll 成功配合。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-16
    • 1970-01-01
    • 1970-01-01
    • 2012-07-24
    • 2018-01-15
    • 2013-02-26
    • 2019-05-28
    相关资源
    最近更新 更多