プラグインdllを別のAppDomainにロードしようとしていますが、Load()メソッドがFileNotFoundExceptionで失敗します。また、AppDomainSetupのPrivateBinPathプロパティを設定しても効果はありません。ログには「Initial PrivatePath = NULL」が表示されるためです。すべてのプラグインは強力な名前を持っています。通常、各プラグインは[Application startp path] \ postplugins \ [plugindir]に格納されています。プラグインのサブディレクトリを[Application startp path]ディレクトリに置くと、すべて動作します。私はまた、AppBaseプロパティを手動で変更しようとしましたが、変更はありません。
ここではコードです:FileNotFoundExceptionでAppDomain.Load()が失敗する
public void LoadPostPlugins(IPluginsHost host, string pluginsDir)
{
_Host = host;
var privatePath = "";
var paths = new List<string>();
//build PrivateBinPath
var dirs = new DirectoryInfo(pluginsDir).GetDirectories();
foreach (var d in dirs)
{
privatePath += d.FullName;
privatePath += ";";
}
if (privatePath.Length > 1) privatePath = privatePath.Substring(0, privatePath.Length - 1);
//create new domain
var appDomainSetup = new AppDomainSetup { PrivateBinPath = privatePath };
Evidence evidence = AppDomain.CurrentDomain.Evidence;
var sandbox = AppDomain.CreateDomain("sandbox_" + Guid.NewGuid(), evidence, appDomainSetup);
try
{
foreach (var d in dirs)
{
var files = d.GetFiles("*.dll");
foreach (var f in files)
{
try
{
//try to load dll - here I get FileNotFoundException
var ass = sandbox.Load(AssemblyName.GetAssemblyName(f.FullName));
var f1 = f;
paths.AddRange(from type in ass.GetTypes()
select type.GetInterface("PluginsCore.IPostPlugin")
into iface
where iface != null
select f1.FullName);
}
catch (FileNotFoundException ex)
{
Debug.WriteLine(ex);
}
}
}
}
finally
{
AppDomain.Unload(sandbox);
}
foreach (var plugin in from p in paths
select Assembly.LoadFrom(p)
into ass
select
ass.GetTypes().FirstOrDefault(t => t.GetInterface("PluginsCore.IPostPlugin") != null)
into type
where type != null
select (IPostPlugin)Activator.CreateInstance(type))
{
plugin.Init(host);
plugin.GotPostsPartial += plugin_GotPostsPartial;
plugin.GotPostsFull += plugin_GotPostsFull;
plugin.PostPerformed += plugin_PostPerformed;
_PostPlugins.Add(plugin);
}
}
そして、ここでログです:
'FBTest.vshost.exe' (Managed (v4.0.30319)): Loaded 'D:\VS2010Projects\PNotes - NET\pnfacebook\FBTest\bin\Debug\postplugins\pnfacebook\pnfacebook.dll', Symbols loaded.
A first chance exception of type 'System.IO.FileNotFoundException' occurred in FBTest.exe
System.IO.FileNotFoundException: Could not load file or assembly 'pnfacebook, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9e2a2192d22aadc7' or one of its dependencies. The system cannot find the file specified.
File name: 'pnfacebook, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9e2a2192d22aadc7'
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection)
at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
at System.Reflection.Assembly.Load(String assemblyString)
at System.UnitySerializationHolder.GetRealObject(StreamingContext context)
at System.AppDomain.Load(AssemblyName assemblyRef)
at PNotes.NET.PNPlugins.LoadPostPlugins(IPluginsHost host, String pluginsDir) in D:\VS2010Projects\PNotes - NET\pnfacebook\FBTest\PNPlugins.cs:line 71
=== Pre-bind state information ===
LOG: User = ANDREYHP\Andrey
LOG: DisplayName = pnfacebook, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9e2a2192d22aadc7
(Fully-specified)
LOG: Appbase = file:///D:/VS2010Projects/PNotes - NET/pnfacebook/FBTest/bin/Debug/
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: pnfacebook, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9e2a2192d22aadc7
LOG: Attempting download of new URL file:///D:/VS2010Projects/PNotes - NET/pnfacebook/FBTest/bin/Debug/pnfacebook.DLL.
LOG: Attempting download of new URL file:///D:/VS2010Projects/PNotes - NET/pnfacebook/FBTest/bin/Debug/pnfacebook/pnfacebook.DLL.
LOG: Attempting download of new URL file:///D:/VS2010Projects/PNotes - NET/pnfacebook/FBTest/bin/Debug/pnfacebook.EXE.
LOG: Attempting download of new URL file:///D:/VS2010Projects/PNotes - NET/pnfacebook/FBTest/bin/Debug/pnfacebook/pnfacebook.EXE.
James、ありがとう!最後に、MarshalByRefObjectの使い方についての明確な説明があります。残念ながら、私は答えが有用であると評価するには十分な評判がありません(少なくとも15が必要です):( – dedpichto
問題なし!喜んで助けました:) –
これを試してみると、LoadPluginsメソッドを汎用化しましたが、SerializationExceptionが発生します。それがなぜあるのかについての示唆はありますか?アセンブリがサンドボックスアプリケーションドメインに読み込まれていることがわかります。 –