Loading .NET Assembly From Memory Instead of Disk [closed]
Asked Answered
C

1

10

I am having a perplexing problem trying to load a .NET assembly from memory instead of from the disk. If I compile the assembly and then load it from disk (either using LoadFile or LoadFrom), then the application works just fine.

However, if I include the compiled assembly DLL file as an embedded resource in the project and then use Assembly.Load to load the bytes from the resource stream, then I get a series of random errors as the application continues to run.

This is only a problem on one of eight assemblies in the application - all of the others work fine from either the disk or memory.

Thanks for the help!

Coleencolella answered 19/11, 2013 at 19:1 Comment(1)
You'll need to include more information about the errors you're getting and under what circumstances they occur.Glossa
I
16

You have not provided enough detail for me to even guess at what your problem is. However, I can present the pattern I use.

The way I handle embedding dependent assemblies is to use the AssemblyResolve event. You wire up the event once and then if the CLR cannot find the assembly on disk it will raise this event. When the event is raised then you extract the assembly bits from the resource manifest and call Assembly.Load.

Here is what the code might look like.

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;
      }
  }
}

And then it can be used like this.

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!
}

I have used this pattern successfully for many years. There are a few caveats, but for the most part it works well. It is certainly a lot better than using the ILMerge tool.

Incommunicado answered 19/11, 2013 at 19:19 Comment(3)
This is the simplest solution I've seen so for single executable apps. Very nice.Antihistamine
Sadly this doesn't work anymore. For some reason Assembly.Load(data) now always fails for security reasons. Writing data to a file with the expected name on disk and then loading it works though (for now). I guess the loading from file thing is safer, because that gives antivirus software a change to prevent malicious data from being loaded.Tillandsia
@RobertJørgensgaardEngdahl Exactly what "security reasons" does the exception say? Are you targeting .NET Framework or .NET Core?Morley

© 2022 - 2025 — McMap. All rights reserved.