11

我注意到有一种方法System.Reflection.Assembly,即Assembly Load(byte[] rawAssembly)

我想知道是否有相反的操作,如byte[] Store(Assembly assembly). 如果没有,我如何将程序集对象转换byte[]为完全在内存中调用Assembly Load(byte[] rawAssembly)而不将程序集写入文件?谢谢!

评论:问题来自我使用第三方库的情况,该库向我返回了一个 Assembly 实例,我必须使用反射来调用它的方法。我不知道库是如何创建这个程序集对象的。我只是想知道我是否可以将程序集对象存储到 byte[] 并使用“Assembly Load(byte[] rawAssembly)”重新加载它。谢谢!

4

3 回答 3

6

System.Security.Policy.Hash 能够计算哈希,而不管程序集的位置如何。因此,我们至少有两种方法可以将程序集作为字节数组获取:

1)使用反射:

var hash = new Hash(assembly);
var dllAsArray = (byte[]) hash.GetType()
    .GetMethod("GetRawData", BindingFlags.Instance | BindingFlags.NonPublic)
    .Invoke(hash, new object[0]);

2) 使用假的 HashAlgorithm 实现:

public class GetWholeBodyPseudoHash : HashAlgorithm
{
    protected override void Dispose(bool disposing)
    {
        if(disposing) _memoryStream.Dispose();
        base.Dispose(disposing);
    }

    static GetWholeBodyPseudoHash()
    {
        CryptoConfig.AddAlgorithm(typeof(GetWholeBodyPseudoHash), typeof(GetWholeBodyPseudoHash).FullName);
    }

    private MemoryStream _memoryStream=new MemoryStream();
    public override void Initialize()
    {
        _memoryStream.Dispose();
        _memoryStream = new MemoryStream();
    }

    protected override void HashCore(byte[] array, int ibStart, int cbSize)
    {
        _memoryStream.Write(array, ibStart, cbSize);
    }

    protected override byte[] HashFinal()
    {
        return _memoryStream.ToArray();
    }
}

...
var bytes = new Hash(yourAssembly).GenerateHash(new GetWholeBodyPseudoHash());
于 2017-09-14T02:50:42.533 回答
4

要将程序集从 AppDomain 转换为 byte[],请使用:

var pi = assembly.GetType().GetMethod("GetRawBytes", BindingFlags.Instance | BindingFlags.NonPublic);
byte[] assemblyBytes = (byte[]) pi.Invoke(assembly, null);
于 2019-01-25T20:02:41.930 回答
2

System.Reflection.Assembly 实现 ISerializable。创建 BinaryFormatter 的实例并在任何流上调用其 Serialize 方法 - MemoryStream、FileStream 等。

Assembly yourAssembly;
var formatter = new BinaryFormatter();
var ms = new MemoryStream();
formatter.Serialize(ms, yourAssembly);
var reloadedAssembly = Assembly.Load(ms.GetBuffer()); 
于 2013-06-03T03:09:51.363 回答