8

I Am working on a task in which i have to load dll and get some information from it like class names and etc... but when i load that dll into my code, it gets locked and can't be build from source code until i close loading program, I have tried certain solution but none of them works for me

  1. Shadowcopy: in this case when i shadow copy assembly then after that if i have changed something in
    my main dll it will be still old one in my loading application.

  2. System.Reflection.assembly.loadfrom(System.IO.GetBytes("asm-path")); //work sometimes but not always

  3. System.Reflection.assembly.ReflectionOnlyConext(); //Does not work

Is there any proper solution to this

Numan Hanif
  • 246
  • 2
  • 17
  • 1
    Assembly.LoadFrom() doesn't have an overload that takes byte[] and there certainly is no method named GetBytes() in System.IO. Pretty sloppy research. Assembly.Load(byte[]) most certainly cannot put a lock on a file. Don't use it. – Hans Passant Sep 21 '13 at 18:12

2 Answers2

27

One way would be to read the bytes of a file and use the overload of Assembly.Load that takes in a byte array similar to what you're doing in your second example. I'm not sure what System.IO.GetBytes is but try File.ReadAllBytes instead.

byte[] assemblyBytes = File.ReadAllBytes("asm-path");
var assembly = Assembly.Load(assemblyBytes);

However this may not be enough depending on what you want to do since you can't unload an assembly after it's been loaded. To workaround this, if you need to, you could load the assembly into its own AppDomain and then unload the AppDomain once you've finished with it.

AppDomain ad = AppDomain.CreateDomain("New_Assembly_AD");
byte[] assemblyBytes = File.ReadAllBytes("asm-path");
var assembly = ad.Load(assemblyBytes);  

Once you've finished with the assembly object, you can unload the AppDomain.

AppDomain.Unload(ad);
Daniel Fisher lennybacon
  • 3,865
  • 1
  • 30
  • 38
keyboardP
  • 68,824
  • 13
  • 156
  • 205
  • AppDomains with shadow-copy is the only way you're going to accomplish this properly. – Cory Nelson Sep 21 '13 at 18:24
  • 3
    New appdomain is the only sane approach... Note that reflection must be done in that new AppDomain too to avoid leaking types into original domain (that would load assembly into original domain too and all effort is wasted). – Alexei Levenkov Sep 21 '13 at 18:35
  • @AlexeiLevenkov - Good call explicitly mentioning that the work should be done in the new AppDomain, thanks. – keyboardP Sep 21 '13 at 20:28
  • @AlexeiLevenkov Kindly provide some code example for [Note that reflection must be done in that new AppDomain too to avoid leaking types into original domain] – Numan Hanif Sep 23 '13 at 13:43
  • @RoyaanKhan - http://www.bing.com/search?q=c%23+run+code+separate+appdomain like http://msdn.microsoft.com/en-us/library/ms173139(v=vs.90).aspx – Alexei Levenkov Sep 23 '13 at 17:53
  • This does not work with mixed mode native assemblies. – TarmoPikaro Nov 26 '18 at 18:02
0

Maybe simply try to release the file after you examined the information? This way it might be locked for a few milliseconds only.

If this is not working. Copy the dll and use the copy...

If you want to refresh the information whenever the dll changes, you could write a directory listener and do something whenever the original dll has been updated.

MichaC
  • 13,104
  • 2
  • 44
  • 56