Freeing Assembly References in C#

Started by
0 comments, last by a_loho 12 years, 10 months ago
Hi Guys,

Im having a little trouble with an C# application i'm writing that has plugin. Basically If i add a new plugin (copy it into the plugin folder) with the same name as an existing plugin or if i come across a faulty plugin i want to delete the .dll file.

However it doesn't let me delete the file stating "The File or folder is in use", I assume the application in question is my application and i haven't freed it somehow. Thing is with that though is that if you look at the load plug in function below in the try catch, if its going to fail it often fails on the "Get types" for loop so by the time i get to the catch i assume that pluginAssembly has gone out of scope and therefore i should have no reference? interestingly however I am allowed to move the file and rename it! and i was thinking i could use that as a "mark for deletion" mechanism but it seems hacky. I'm wondering how i can best release this object some kind of Assembly.unload()?? i tried using(Assembly pluginAssembly = Assembly.LoadFrom(filename)) but it protested that Assembly was not derived from IDisposable...which i could have sworn it was!

Any idea whats going on here and what a clean fix would be?

Thanks!, Chris


Adding new Plug:
[source]



CleanUpAndClosePlugins();

//check for directory
if (!Directory.Exists(PluginDir))
{
try
{
Directory.CreateDirectory(PluginDir);
}
catch(Exception exept)
{

}
}


OpenFileDialog fd = new OpenFileDialog();
if (fd.ShowDialog() == DialogResult.OK)
{
foreach (string filename in fd.FileNames)
{
string newName = PluginDir+"\\" + Path.GetFileNameWithoutExtension(filename) + ".dll";


try
{
File.Move(newName, PluginDir + "\\" + Path.GetFileNameWithoutExtension(newName) + ".OLD");
// File.Delete(newName);

File.Copy(filename, newName);
}
catch (System.Exception ex)
{
MessageBox.Show("Unable to overwrite\n " + newName + "\n with \n" + filename + " try closing application and starting again");
}

}
}
LoadInstalledPluggins();

}
[/source]

Load a plug in:
[source]

try
{

//Create a new assembly from the plugin file we're adding..
Assembly pluginAssembly = Assembly.LoadFrom(FileName);


if (pluginAssembly == null)
return;


//Next we'll loop through all the Types found in the assembly
foreach (Type pluginType in pluginAssembly.GetTypes())
{
if (pluginType.IsPublic) //Only look at public types
{
if (!pluginType.IsAbstract) //Only look at non-abstract types
{
//Gets a type object of the interface we need the plugins to match
Type typeInterface = pluginType.GetInterface("PluginInterface.IPlugin", true);

//Make sure the interface we want to use actually exists
if (typeInterface != null)
{
//Create a new available plugin since the type implements the IPlugin interface
Types.AvailablePlugin newPlugin = new Types.AvailablePlugin();

//Set the filename where we found it
newPlugin.AssemblyPath = FileName;
newPlugin.pluginType = pluginType;

bool enabled = false;

if (Properties.Settings.Default.EnabledPluginList != null)
enabled = Properties.Settings.Default.EnabledPluginList.Contains(FileName);

//Add the new plugin to our collection here
this.PluginslistBox.Items.Add(newPlugin, enabled);

//cleanup a bit
newPlugin = null;
}

typeInterface = null; //Mr. Clean
}
}
}

pluginAssembly = null; //more cleanup
}
catch (System.Exception ex)
{
MessageBox.Show("Invalid plugin in pluggins directory:, will be deleted " + FileName + "\n\nDetails"+ex.Message);
//File.Delete(FileName);
File.Move(FileName, PluginDir + "\\" + Path.GetFileNameWithoutExtension(FileName) + ".OLD");

}



}
[/source]
Advertisement
You can only unload appdomain and not single assemblies. If you want to be able to unload assemblies during runtime you have to launch them in their own appdomain.

This topic is closed to new replies.

Advertisement