43

I'm loading a DLL via System.Reflection.Assembly.LoadFile and reflecting over it's members in a plugin-esque system. I need to be able to update/overwrite these DLL while the system is running but it appears that after calling System.Reflection.Assembly.LoadFile the file is subsequently locked.
Does anyone know of a way to unlock the file?
I have read about loading the file in a separate appdomain? Are there any pitfalls to this approach?

Robert
  • 1,286
  • 1
  • 17
  • 37
Adam Naylor
  • 6,172
  • 10
  • 49
  • 69

2 Answers2

76

If you use this:

 System.Reflection.Assembly.Load(System.IO.File.ReadAllBytes(path))

It will not lock the file.

Edit


While this works, it is not the best solution, but the better way of doing it is a lot more involved (too much for just pasting all the code here for it).

I have created a public repository on Github here with all the code for doing this properly:

Loading Assemblies without Locking by using Shadow Copying.

Pondidum
  • 11,457
  • 8
  • 50
  • 69
  • That worked perfectly! I'll leave this open just to see if anyone covers some of the other points... – Adam Naylor Jun 23 '09 at 09:10
  • Glad it worked for you :) I have never tried the AppDomain method, although I did read a little about it while looking for a solution to this very problem. – Pondidum Jun 23 '09 at 09:17
  • 8
    The down-side of this approach would probably be that you cannot 'unload' the assembly from memory, meaning each time you update the DLL and reload you end up with another copy in-memory. The AppDomain method is a bit more circumspect and has a (slight?) performance down-side, but it does mean that you can unload the AppDomain when you no longer need it. – jerryjvl Jun 23 '09 at 09:40
  • This saved me from missing my deadline. Thank you so much! – Scott Dec 15 '09 at 02:38
  • 1
    This will work only for standalone libs. If the dll at path has a sub dependency, the assembly loader will be unable to resolve them. – Jan Apr 27 '10 at 00:39
  • @AdamNaylor: I know this is quite an old question/answer, but I have updated it with a link to the proper solution. – Pondidum Dec 13 '12 at 13:51
0

Use Microsoft.Cci included in Microsoft FxCop

Sample for version 1.35:

using Microsoft.Cci;
// [...]
AssemblyNode assembly = AssemblyNode.GetAssembly(path);
Sven Hecht
  • 1,337
  • 1
  • 16
  • 23