2

I'm trying to load an assembly, use Reflection to get all the class' inside that .dll, and then delete the .dll. However I am getting access denied exception when trying to delete the .dll. This is not due to access rights as I can delete the .dll if I do not load it first.

I've looked on MSDN, and apparently there is no way to "unload", but I'm hoping that there might be another way.

Assembly assembly;
assembly = Assembly.LoadFrom(filepath);

Type[] listOfAllClassInDll = assembly.GetTypes();
List<string> listOfAllClassNamesInDll = new List<string>();

        foreach (Type classInDll in listOfAllClassInDll)
        {
           listOfAllClassNamesInDll.Add(classInDll.Name);
        }

File.Delete(filepath);
Michael
  • 57,169
  • 9
  • 80
  • 125
Ralt
  • 2,084
  • 1
  • 26
  • 38
  • 1
    See http://stackoverflow.com/questions/225330/how-to-load-a-net-assembly-for-reflection-operations-and-subsequently-unload-it or use Mono.Cecil – xanatos Apr 16 '15 at 07:41
  • @xanatos It seems none of my class' can be loaded using ReflectionOnlyLoadFrom, they all throw a 'ReflectionTypeLoadException'. Not sure if this is a problem that I can get around some how. – Ralt Apr 16 '15 at 08:01
  • In general you'll have to load them in another AppDomain if you want to unload them. It isn't "good" to load assemblies and then just unload them. They could do "things" upon being loaded. For this reason there is the `ReflectionOnlyLoadFrom`. I suggest you try `Mono.Cecil` – xanatos Apr 16 '15 at 08:05

2 Answers2

1

Actually you can't do it straightforward.. There is why: http://blogs.msdn.com/b/jasonz/archive/2004/05/31/145105.aspx

But you can dynamically load your assembly in another AppDomain. Then when you don't need your assembly - you have to unload you AppDomain with loaded assembly.

Example there: https://bookie.io/bmark/readable/9503538d6bab80

Andrii Tsok
  • 1,386
  • 1
  • 13
  • 26
0

Instead of using LoadFrom/LoadFile you can use Load with File.ReadAllBytes. Here you do not use assembly file directly but read it's content and use the read data. So, you are free to rename/delete the file.

Your code will then look like:

Assembly assembly;
assembly = Assembly.Load(File.ReadAllBytes(filepath));

Type[] listOfAllClassInDll = assembly.GetTypes();
List<string> listOfAllClassNamesInDll = new List<string>();

foreach (Type classInDll in listOfAllClassInDll)
{
   listOfAllClassNamesInDll.Add(classInDll.Name);
}

File.Delete(filepath);

Hope this helps :)

Hardik
  • 764
  • 5
  • 10