加载字节数组程序集 [英] Loading Byte Array Assembly

查看:75
本文介绍了加载字节数组程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试仅使用字节数组加载程序集,但无法弄清楚如何使其正常工作.这是设置:

I'm experimenting with loading an assembly using just byte arrays, but I can't figure out how to get it to work properly. Here is the setup:

public static void Main() 
{
    PermissionSet permissions = new PermissionSet(PermissionState.None);
    AppDomainSetup setup = new AppDomainSetup { ApplicationBase = Environment.CurrentDirectory };
    AppDomain friendlyDomain = AppDomain.CreateDomain("Friendly", null, setup, permissions);

    Byte[] primary = File.ReadAllBytes("Primary.dll_");
    Byte[] dependency = File.ReadAllBytes("Dependency.dll_");

    // Crashes here saying it can't find the file.
    friendlyDomain.Load(dependency);

    AppDomain.Unload(friendlyDomain);

    Console.WriteLine("Stand successful");
    Console.ReadLine();
}

我创建了两个模拟dll,并有意将其扩展名重命名为".dll_",因此系统将无法找到物理文件. primarydependency都可以正确填充,但是当我尝试使用二进制数据调用AppDomain.Load方法时,它会返回:

I created two mock dlls, and renamed their extension to '.dll_' intentionally so the system wouldn't be able to find the physical files. Both primary and dependency fill correctly, but when I try to call the AppDomain.Load method with the binary data, it comes back with:

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

为什么要在系统中搜索文件?

Why would it be searching the system for a file?

更新

另一方面,这似乎可行:

This on the other hand seems to work:

public class Program {
    public static void Main() {
        PermissionSet permissions = new PermissionSet(PermissionState.Unrestricted);
        AppDomainSetup setup = new AppDomainSetup { ApplicationBase = Environment.CurrentDirectory };
        AppDomain friendlyDomain = AppDomain.CreateDomain("Friendly", null, setup, permissions);

        Byte[] primary = File.ReadAllBytes("Primary.dll_");
        Byte[] dependency = File.ReadAllBytes("Dependency.dll_");

        // Crashes here saying it can't find the file.
        // friendlyDomain.Load(primary);

        Stage stage = (Stage)friendlyDomain.CreateInstanceAndUnwrap(typeof(Stage).Assembly.FullName, typeof(Stage).FullName);
        stage.LoadAssembly(dependency);

        Console.WriteLine("Stand successful");
        Console.ReadLine();
    }

}

public class Stage : MarshalByRefObject {
    public void LoadAssembly(Byte[] data) {
        Assembly.Load(data);
    }
}

因此AppDomain.LoadAssembly.Load之间似乎有所不同.

So it appears there is a difference between AppDomain.Load and Assembly.Load.

推荐答案

这是正常现象,CLR在搜索主要"所需的程序集时并不认为您加载的依赖项"是合适的程序集.与加载上下文"相关的问题,没有这样的程序集加载.这是有意的,CLR无法确保DLL Hell不会成为问题,因为它不知道程序集来自何处.由于您打开了DLL Hell的大门,因此您还必须避免自己陷入地狱.

This is normal, the CLR doesn't consider the "dependency" you loaded to be a suitable assembly when it searches for the assembly that "primary" needs. A problem associated with "loading context", there isn't one for assemblies loaded like this. This is intentional, the CLR cannot ensure that DLL Hell won't be an issue since it has no idea where the assembly came from. Since you opened the door to DLL Hell, you also have to avoid hell yourself.

您将需要实现AppDomain.AssemblyResolve事件.当CLR无法找到依赖项"时,它将触发,您可以返回从Assembly.Load(byte [])获得的程序集.但是,对于同一程序集不止一次触发时,您将必须始终如一地执行操作,换句话说,返回完全相同的程序集,否则,.NET类型标识会引发更多问题.产生难以理解的强制转换例外,不能将Foo转换为Foo"样式.

You'll need to implement the AppDomain.AssemblyResolve event. It will fire when the CLR cannot find "dependency", you can return the assembly you get from Assembly.Load(byte[]). You will however have to do so consistently when it fires more than once for the same assembly, in other words return the exact same Assembly, or you'll have more problems induced by .NET type identity. Producing hard to understand casting exceptions, "can't cast Foo to Foo" style.

还有其他问题,效率很低.程序集的虚拟内存无法由磁盘上的文件支持,因此由分页文件支持.这会增加您的流程的提交大小.

There are other problems, it is rather inefficient. The virtual memory for the assembly cannot be backed by a file on disk so it is backed by the paging file. Which increases the commit size for your process.

最好不要这样做.

这篇关于加载字节数组程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆