Tôi đang cố tải dll plugin của mình vào AppDomain riêng biệt, nhưng phương thức Load() không thành công với FileNotFoundException. Hơn nữa, nó có vẻ như thiết lập tài sản PrivateBinPath của AppDomainSetup không có hiệu lực, bởi vì trong log tôi thấy "Initial PrivatePath = NULL". Tất cả các plugin đều có tên mạnh. Thông thường, mỗi plugin được lưu trữ trong [Đường dẫn khởi động ứng dụng] \ postplugins \ [plugindir]. Nếu tôi đặt các thư mục con plugin dưới [Đường dẫn khởi động ứng dụng] thư mục, mọi thứ đều hoạt động. Tôi cũng đã cố gắng thay đổi thuộc tính AppBase bằng tay nhưng nó không thay đổi.
Đây là mã:AppDomain.Load() không thành công với FileNotFoundException
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);
}
}
Và đây là nhật ký:
'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, cảm ơn bạn rất nhiều! Cuối cùng tôi thấy lời giải thích rõ ràng về việc sử dụng MarshalByRefObject. Thật không may, tôi không có đủ danh tiếng để đánh dấu câu trả lời là hữu ích (cần ít nhất 15) :( – dedpichto
Không có vấn đề gì! Rất vui khi được giúp :) –
Khi tôi thử điều này, mặc dù tôi đã thực hiện phương pháp LoadPlugins-generic, tôi nhận được một SerializationException. Bất kỳ đề xuất nào về lý do tại sao điều đó có thể là? Tôi có thể thấy rằng hội đồng đã được tải trong miền ứng dụng sandbox. –