我想拦截插件和主机程序集之间的通信。
我试图加载ThirdPartyPlugin.dll
到AppDomain沙箱(下面的代码)中,以拦截它加载HostLibrary.dll
程序集的尝试(我正在使用处理AssemblyResolve事件的技巧)。而不是原来的HostLibrary.dll
,然后我试图注入一个假的,具有一些不同的功能。
不幸的是,原来HostLibrary.dll
是一个Strong Named Assembly,我认为正因为如此,我在我的程序中遇到了如下异常:
未处理的异常:System.IO.FileLoadException:无法加载文件或程序集“HostLibrary,版本=7.0.0.0,Culture=neutral,PublicKeyToken=1a2b3c4d5e6f7890”或其依赖项之一。找到的程序集的清单定义与程序集引用不匹配。(来自 HRESULT 的异常:0x80131040)---> System.IO.FileLoadException:定位的程序集的清单定义与程序集引用不匹配。(来自 HRESULT 的异常:0x80131040)
我创建的假程序集与原始程序集的名称 ( "HostLibrary"
) 和版本 ( ) 匹配;"7.0.0.0"
有一次我认为我什至让它明显匹配PublicKeyToken
(当我打印Assembly.FullName时,它是相同的),但异常仍然发生。
您对我如何解决此问题有任何想法吗?有可能完全解决吗?它是因为数字签名还是其他原因而发生的?如果签名,那么是否可以禁用检查?实际上,通过阅读Ian Picknell 的一篇文章,我认为我真的不应该遇到这个问题......那么有什么问题吗?
代码是:
static void Main(string[] args)
{
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationName = "WrapperBuddy";
setup.ApplicationBase = System.Environment.CurrentDirectory;
AppDomain sandbox = AppDomain.CreateDomain("SandboxBuddy", null, setup);
sandbox.AssemblyResolve += delegate(object sender, ResolveEventArgs args)
{
String name = new AssemblyName(args.Name).Name;
return BuildFakeAssembly(name);
};
sandbox.DoCallBack(delegate()
{
Assembly plugin = LoadAssembly(PLUGIN_DIR, "ThirdPartyPlugin");
System.Console.WriteLine(plugin.GetExportedTypes()); // (1)
});
}
辅助函数定义为:
static Assembly LoadAssembly(String dir, String name)
{
string path = Path.Combine(dir, name) + ".dll";
return Assembly.Load(File.ReadAllBytes(path));
}
static Assembly BuildFakeAssembly(String name)
{
AssemblyName aName = new AssemblyName(name);
// see: http://msdn.microsoft.com/en-us/library/w58ww7se%28v=vs.85%29.aspx
// http://msdn.microsoft.com/en-us/library/w58ww7se%28v=vs.100%29.aspx
aName.KeyPair = new StrongNameKeyPair(new FileStream(@"MyKey.snk", FileMode.Open));
// MyKey.snk is a random key generated using sn.exe
aName.Version = new Version("7.0.0.0");
//aName.SetPublicKeyToken(new byte[] { 0x11, 0x22, ... }); // didn't help
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(
aName, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");
return ab;
}
我会很感激任何帮助。