首页 > 解决方案 > “无法加载程序集”,但程序集已加载

问题描述

我正在开发一个简单的 WPF 应用程序,它使用两个外部 DLL,Nancy.dllNancy.Hosting.Self.dll通过 http 发送一些数据。我想保持 .exe 文件独立,所以我试图将两个 .dll 文件合并到应用程序中。我尝试了多种构建后合并方法,例如NetZand ILMerge,但两者似乎都存在 wpf 应用程序问题并且没有输出工作可执行文件。

这篇文章对解决这个问题有多种建议,尽管它们都归结为相同的两件事:

  1. 使用构建后合并。这在我的情况下效果不佳。
  2. 将 DLL 作为嵌入式资源放入应用程序中,并AppDomain.CurrentDomain.AssemblyResolve在必要时利用事件加载它。

第二种选择似乎很有希望:事件被触发,它找到嵌入的资源,从中生成数据流并将其作为程序集加载。我可以验证程序集是否以多种方式加载:
Visual StudioDebug -> Windows -> Modules显示加载的程序集,
AppDomain.CurrentDomain.GetAssemblies()还显示正在加载的程序集。

但是,在使用程序集(在本例中为调用Nancy.Hosting.Self.NancyHost host = new NancyHost();)时,我仍然收到以下错误:

Could not load file or assembly 'Nancy, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

我确实确保所有依赖项也被加载(如此处所建议并且所有加载的程序集都在同一个 AppDomain 中。另请注意,上述错误仅适用于Nancy.dll,该AssemblyResolve事件确实可以Nancy.Hosting.Self.dll正确加载。

我真的不知道我可能做错了什么,以及我加载程序集是否有问题,或者是否特别是 Nancy 行为异常(我在 GitHub 上发现了这个问题,我不确定它是否相关) . 如果您对加载程序集、合并 dll 或 Nancy 的替代方案有任何建议,我会很高兴听到。

PS:
我尝试从 调用不同的方法Nancy.dll,令我惊讶的是我能够;该AssemblyResolve方法确实有效。
不过,初始化 aNancy.Hosting.Self.NancyHost仍然存在问题,堆栈跟踪提示了原因:

   at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName)
   at Nancy.AppDomainAssemblyCatalog.CreateRemoteReferenceProber(AppDomain appDomain)
   at Nancy.AppDomainAssemblyCatalog.LoadNancyReferencingAssemblies(IEnumerable`1 loadedAssemblies)
   at Nancy.AppDomainAssemblyCatalog.GetAvailableAssemblies()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Nancy.DefaultTypeCatalog.GetTypesAssignableTo(Type type)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Nancy.DefaultTypeCatalog.GetTypesAssignableTo(Type type, TypeResolveStrategy strategy)
   at Nancy.Bootstrapper.NancyBootstrapperLocator.GetBootstrapperType(ITypeCatalog typeCatalog)
   at Nancy.Bootstrapper.NancyBootstrapperLocator.LocateBootstrapper()
   at Nancy.Bootstrapper.NancyBootstrapperLocator.get_Bootstrapper()

因此,显然,当 Nancy 初始化其引导程序时,它会尝试获取其引用程序集并为此使用GetAssemblyDirectories方法。自然地,DLL 不存在(因为我试图将它们合并到 .exe 中)并且引导程序无法初始化。

由于我无法解决这个问题,并且 Nancy 不再被维护,我想重申我的问题:
有人知道用于 c# 的轻量级 Web 框架吗?

标签: c#wpfdllassembliesnancy

解决方案


我真的不想去寻找其他东西,因为Nancy它对我来说很好用。我最终做的是将 dll 写入我知道 nancy 会寻找它的地方,初始化该引导程序,然后再次删除数据:

bool NancyPresent = File.Exists("Nancy.dll");
if (!NancyPresent) {
    var assembly = Assembly.GetExecutingAssembly();
    using (Stream stream = assembly.GetManifestResourceStream("Resources.Nancy.dll"))
    using (MemoryStream MS = new MemoryStream()) {
        stream.CopyTo(MS);
        File.WriteAllBytes("Nancy.dll", MS.ToArray());
    }
    Nancy.Bootstrapper.INancyBootstrapper bootstrapper = Nancy.Bootstrapper.NancyBootstrapperLocator.Bootstrapper;
    bootstrapper.Initialise();
    File.Delete("Nancy.dll");
}

外卖消息是 dll 加载正常,尽管 Nancy 的错误表明并非如此。即使它是开源的,你也永远不知道第三方软件包到底会做什么!


推荐阅读