从内存而不是磁盘加载.NET程序集[关闭]

Posted

技术标签:

【中文标题】从内存而不是磁盘加载.NET程序集[关闭]【英文标题】:Loading .NET Assembly From Memory Instead of Disk [closed] 【发布时间】:2013-11-19 19:01:54 【问题描述】:

我在尝试从内存而不是磁盘加载 .NET 程序集时遇到了一个令人费解的问题。如果我编译程序集然后从磁盘加载它(使用 LoadFile 或 LoadFrom),那么应用程序就可以正常工作。

但是,如果我将已编译的程序集 DLL 文件作为嵌入资源包含在项目中,然后使用 Assembly.Load 从资源流中加载字节,那么在应用程序继续运行时会出现一系列随机错误。

这只是应用程序中八个程序集之一的问题 - 所有其他程序集在​​磁盘或内存中都可以正常工作。

感谢您的帮助!

【问题讨论】:

您需要提供有关您遇到的错误以及它们在什么情况下发生的更多信息。 【参考方案1】:

你没有提供足够的细节让我猜测你的问题是什么。不过,我可以展示我使用的模式。

我处理嵌入依赖程序集的方式是使用AssemblyResolve 事件。您将事件连接一次,然后如果 CLR 在磁盘上找不到程序集,它将引发此事件。引发事件时,您从资源清单中提取程序集位并调用Assembly.Load

下面是代码的样子。

internal class AssemblyResolver

  public static void Register()
  
    AppDomain.CurrentDomain.AssemblyResolve +=
      (sender, args) =>
      
        var an = new AssemblyName(args.Name);
        if (an.Name == "YourAssembly")
        
          string resourcepath = "YourNamespace.YourAssembly.dll";
          Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourcepath);
          if (stream != null)
          
            using (stream)
            
              byte[] data = new byte[stream.Length];
              stream.Read(data, 0, data.Length);
              return Assembly.Load(data);
            
          
        
        return null;
      
  

然后就可以这样使用了。

public static void Main()

  // Do not use any types from the dependent assembly yet.

  AssemblyResolver.Register();

  // Now you can use types from the dependent assembly!

我多年来一直成功地使用这种模式。有一些警告,但在大多数情况下它运作良好。这肯定比使用 ILMerge 工具好很多。

【讨论】:

这是我见过的最简单的解决方案,适用于单个可执行应用程序。非常好。 遗憾的是这不再起作用了。出于某种原因,Assembly.Load(data) 现在出于安全原因总是失败。将数据写入磁盘上具有预期名称的文件,然后加载它(目前)。我想从文件加载更安全,因为这可以让防病毒软件更改以防止加载恶意数据。

以上是关于从内存而不是磁盘加载.NET程序集[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

ReflectionTypeLoadException 从 .Net 4.0 应用程序加载 .Net 4.0 程序集,而 2.0 可以工作

我的 C++ 程序集是如何从 C# 控制台应用程序而不是 ASP.NET 中看到的?

如何将带有 dll 的应用程序从内存加载到 AppDomain 中并执行它?

.NET WCF w3wp 本机内存泄漏和加载程序堆中 0 大小的 18k 动态程序集

LoadFrom 和上下文

C++(MFC,而不是 .NET)应用程序的程序集重定向