プラグインとホスト アセンブリ間の通信を傍受したいと考えています。
AppDomainサンドボックス (以下のコード) にロードして、アセンブリのロードの試行を傍受しようとしました( ThirdPartyPlugin.dll
AssemblyResolveイベントの処理でトリックを使用しています)。元の の代わりに、いくつかの異なる機能を備えた偽の を注入しようとしています。HostLibrary.dll
HostLibrary.dll
残念ながら、オリジナルHostLibrary.dll
はStrong Named Assemblyです。そのため、プログラムで以下のような例外が発生していると思います。
未処理の例外: System.IO.FileLoadException: ファイルまたはアセンブリ 'HostLibrary、Version=7.0.0.0、Culture=neutral、PublicKeyToken=1a2b3c4d5e6f7890' またはその依存関係の 1 つを読み込めませんでした。見つかったアセンブリのマニフェスト定義がアセンブリ参照と一致しません。(HRESULT からの例外: 0x80131040) ---> System.IO.FileLoadException: 見つかったアセンブリのマニフェスト定義がアセンブリ参照と一致しません。(HRESULT からの例外: 0x80131040)
私が作成した偽のアセンブリは、元のアセンブリの名前 ( "HostLibrary"
) とバージョン ( ) に一致します。"7.0.0.0"
一度に明らかに一致させたと思います( Assembly.FullNamePublicKeyToken
を印刷したとき、それは同一でした)が、それでも例外が発生します。
この問題を解決する方法について何か考えはありますか? まったく解決することは可能ですか?デジタル署名またはその他の理由で発生しますか? 署名の場合、チェックを無効にすることは可能ですか? 実際、 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;
}
どんな助けにも感謝します。