4

I have a winform c# app.

I can use a [web method] to check for a version of a DLL that my client winform should use. I can also download it. But, if I copy over the old DLL I will get an error stating that the file is in use. I had expected this.

Is there a way to unload this DLL from my running winform app, copy over the DLL and reload it?

I do not want to use a boot-strapper for my updater and it may come to having to stop and restart my application.

All this will be obsolete if I can just unload my DLL.

I have looked for a long time and cannot find anything. Before I retire on this I thought I would post the question here.

Thanks

PS I could post the code that shows how to load an DLL in code and the error generated from it but it is open knowledge and does not add to this question.

Andrew Simpson
  • 6,883
  • 11
  • 79
  • 179
  • 1
    You would have to create a separate AppDomain which houses your .dll's to load/unload. – Saggio Nov 11 '13 at 18:47
  • 1
    An assembly is loaded for the lifetime of a application domain. If you want to dynamically update, you'll have to have it loaded in a seperate appdomain. Or you could do some AppDomain switching by creating a new one, start your updater in the appdomain, kill main appdomain. have updated do the same but restart your app – Marvin Smit Nov 11 '13 at 18:47
  • So, do you know if it is feasible for my main app to reference a DLL in a different app domain then? Is this what you are suggesting? Thanks – Andrew Simpson Nov 11 '13 at 18:52

2 Answers2

6

Is there a way to unload this DLL from my running winform app, copy over the DLL and reload it?

Not in most cases. The only way to unload a DLL in a managed application is to unload the entire AppDomain. This typically means you need to be very careful about how you use the assembly (you can't just directly reference and use it as normal).

I do not want to use a boot-strapper for my updater and it may come to having to stop and restart my application.

This is the most common approach. Making this work inside the application is essentially building the bootstrapper into the application itself (in its own AppDomain), and unloading/restarting the AppDomain using the assembly. This is typically more work and just as disrupting as a separate bootstrapper application.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Hi, just to add why I do not want a boot-strapper.. it is because I do not want to have to stop/start the app as it is a real-time app needing to be on all the time. – Andrew Simpson Nov 11 '13 at 18:54
  • 2
    @AndrewSimpson You can't unload the process/appdomain without stopping the application, effectively. There's really no way around that. – Reed Copsey Nov 11 '13 at 18:55
  • 1
    @AndrewSimpson You'd have to keep that assembly isolated within it's own AppDomain - depending on what you're using from it, that is possible, but tricky. Look into AppDomain unloading for details. – Reed Copsey Nov 11 '13 at 18:56
  • 2
    I have seen techniques where the DLL is shadow copied before being loaded, so that the original can be overwritten and then shadow copied+loaded again. This solves the file lock problem, but I'm unclear to what happens to the previously loaded assembly version: http://stackoverflow.com/questions/13462525/c-sharp-dynamic-loading-unloading-of-dlls-redux-using-appdomain-of-course – AaronLS Nov 11 '13 at 18:56
  • V interesting everyone. Do you think there would be any mileage in loading code from a string and using the EVAL to compile it at runtime? – Andrew Simpson Nov 11 '13 at 18:58
  • 1
    @AndrewSimpson There is no direct "EVAL" support, either. That's going to get just as ugly, since most implementations that can do anything complicated do dynamic compilation, which causes the generated assembly to get loaded. The shadow copy method above has the same downside - you can keep loading new assemblies, but the only ones never unload, so over time, you have bad things happen... – Reed Copsey Nov 11 '13 at 19:00
  • Hi, yes I do agree with you which is why I have not implemented it. It looks very ugly. Ok, well the way forward is to do a restart. It was what I suspected but was holding out hope :) – Andrew Simpson Nov 11 '13 at 19:02
  • 1
    @AndrewSimpson Unless your logic can be isolated in its own AppDomain, a restart is probably the best option. (isolation is very tough if you need to interact with your program, not just "call some code") – Reed Copsey Nov 11 '13 at 19:03
  • completely agree with you. Thanks – Andrew Simpson Nov 11 '13 at 19:03
0

you are probably looking for something like MEF?

http://mef.codeplex.com/

http://msdn.microsoft.com/en-us/library/dd460648(v=vs.110).aspx

Ahmed ilyas
  • 5,722
  • 8
  • 44
  • 72
  • Hi, many thanks for the advise. I did look at this before but could not see how this could help me. Thanks for your time though – Andrew Simpson Nov 11 '13 at 18:55