问题
i have a weird problem. i would like to delete an assembly(plugin.dll on harddisk) which is already loaded, but the assembly is locked by the operating system (vista), even if i have unloaded it.
f.e.
AppDomainSetup setup = new AppDomainSetup();
setup.ShadowCopyFiles = "true";
AppDomain appDomain = AppDomain.CreateDomain(assemblyName + "_AppDomain", AppDomain.CurrentDomain.Evidence, setup);
IPlugin plugin = (IPlugin)appDomain.CreateInstanceFromAndUnwrap(assemblyName, "Plugin.MyPlugins");
I also need the assemblyinfos, because I don't know which classes in the pluginassembly implements the IPlugin Interface. It should be possible to have more than one Plugin in one Pluginassembly.
Assembly assembly = appDomain.Load(assemblyName);
if (assembly != null) {
Type[] assemblyTypes = assembly.GetTypes();
foreach (Type assemblyTyp in assemblyTypes) {
if (typeof(IPlugin).IsAssignableFrom(assemblyTyp)) {
IPlugin plugin = (IPlugin)Activator.CreateInstance(assemblyTyp);
plugin.AssemblyName = assemblyNameWithEx;
plugin.Host = this;
}
}
}
AppDomain.Unload(appDomain);
How is it possible to get the assemblyinfos from the appDomain without locking the assembly?
best regards
回答1:
I think i've the answer! the answer from Øyvind Skaar will not work, if you would like to delete the loaded assembly.
instead of
using (FileStream dll = File.OpenRead(path))
{
fileContent = new byte[dll.Length];
dll.Read(fileContent, 0, (int)dll.Length);
}
Assembly assembly = appDomain.Load(fileContent);
you have to use
byte[] b = File.ReadAllBytes(assemblyName);
assembly = Assembly.Load(b);
best regards
回答2:
I know this thread is quite dead, but I am currently working on this and I just got the answer (at 1h30 AM...)
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
AppDomain app = AppDomain.CreateDomain("YaCsi", null, setup);
app.DoCallBack(LoaderCallback);
AppDomain.Unload(app);
File.Delete("__YaCsi_Test01.dll");
static void LoaderCallback()
{
byte[] raw = File.ReadAllBytes("__YaCsi_Test01.dll");
Assembly yacsi = Assembly.Load(raw);
((IScript)yacsi.CreateInstance("Script")).Go();
}
And it actually don't throw any exceptions!!! Hope someone will read this and that it will answer there question!
回答3:
If you load the assembly as a stream, it should work.
byte[] fileContent;
string path = "../../../test/bin/Debug/test.dll"; //Path to plugin assembly
using (FileStream dll = File.OpenRead(path))
{
fileContent = new byte[dll.Length];
dll.Read(fileContent, 0, (int)dll.Length);
}
Assembly assembly = appDomain.Load(fileContent);
File.Delete(path);
回答4:
See these pages:
http://connect.microsoft.com/VisualStudio/feedback/details/536783/vsip-assembly-file-handles-not-being-released-after-appdomain-unload
http://msdn.microsoft.com/it-it/library/43wc4hhs.aspx
Set a new AppDomain AppDomainSetup with LoaderOptimization.MultiDomainHost
E.g.
domainnew = AppDomain.CreateDomain(newdomain_name, null, new AppDomainSetup {
ApplicationName = newdomain_name,
ApplicationBase = assembly_directory,
ConfigurationFile = ConfigurationManager.OpenExeConfiguration(assemblylocation).FilePath,
LoaderOptimization = LoaderOptimization.MultiDomainHost,
ShadowCopyFiles = shadowcopy ? "true" : "false",
}
);
回答5:
What we do, is to have one folder that is watched for assemblies. When an assembly is added, the application copies it to a temp directory gives it a unique file name and loads it from there.
When the application is first loaded, it tries to clear out the temp directory.
I don't think that directly answers your question, but it probably solves your problem.
来源:https://stackoverflow.com/questions/425077/how-to-delete-the-pluginassembly-after-appdomain-unloaddomain