Dynamically un referenc a dll in c# winforms - c#

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.

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.

you are probably looking for something like MEF?
http://mef.codeplex.com/
http://msdn.microsoft.com/en-us/library/dd460648(v=vs.110).aspx

Related

Is it possible to reference a COM DLL without registering itself?

I have activated COM registration free DLL when deploying the application. In addition, I have set the Properties->Linker->Register Output to NO in my build process. However now my application which references the DLL no longer builds because it cannot find the reference. So my question is that is it possible to build the application that references the DLL without registering the dll?
Thanks!
You left no breadcrumbs to guess why registration is required to build your code. This is not normally necessary. One random guess is that you are using the Isolated property for a reference in a C# project for a COM component written in C++. Which is a very nice feature, it automatically generates the manifest entries so the program can run reg-free.
But those manifest entries need to come from somewhere if you don't write them yourself. Which is the registry if you use the Isolated property. Chicken-and-egg problem here, you have to register it so it can run unregistered :)
Keep in mind that you use reg-free COM on the user's machine, it isn't important on your dev machine.

Embed Assembly in Winforms application

I have a winforms application which is built dynamically by another application, now the code in the winforms application needs to reference an assembly which I have in a dll. I'd like to embed this in the winforms application somehow so that it doesn't need to be sent with the application to the client.
I've tried the compilerParams.ReferencedAssemblies.Add method but this does seem to let me run the application without still having the assembly in the directory with the application.
I've also tried putting the assembly in the resources of the winforms application and then pulling this back out in the runtime of the winforms application using Assembly.Load, the only problem here is that any references to the assembly don't seem to work so by the look of it I'd have to use reflection to identify the methods in the Assembly dynamically which isn't ideal.
Essentially my question is what's the best way to do this!
Have a look at the ILMerge tool.

How can I use a C# (managed) dll that I don't have?

How can I correctly reference a C# DLL that I don't have physical access to? (I actually have the DLL, just not all it's dependencies.)
Background:
On the target computer, there is a program and many interdependent dll files installed in C:\FancyProgram.
I need to write a simple application that will be deployed on the target computer to C:\SimpleProgram.
This simple program will need to make some calls into one of the dll files under C:\FancyProgram. It is a .net managed DLL
On my development machine, I do not have a copy of FancyProgram. I do have that one DLL file, but I do not have any of it's many dependencies. I also can not bundle that DLL into SimpleProgram.
What is the correct method to use and reference this DLL in my Visual Studio project such that my SimpleProgram will correctly compile but load the DLL at runtime from the correct location?
Thank you
My recommendation is to create a Facades for the functionality you want to use from that dll. And don't use (reference) it directly - resolve and load it dynamically:
C# - Correct Way to Load Assembly, Find Class and Call Run() Method
Load Assembly at runtime and create class instance
.Net will do late binding anyway. As long as you don't reference the .dll in any way until you actually mean to load it this will work.
Simply encapsulate all references (fields, properties, methods, instances) into a spearate class or project and make an instance only when you have to. You can then try-catch the load error.
See Visual Studio Output window when your app is run, it will tell you when its is attempting to load what .dll.
You may also want to look at these events to make your app handle errors gracefully:
AppDomain.CurrentDomain.AssemblyLoad += ...;
AppDomain.CurrentDomain.AssemblyResolve += ...;
AppDomain.CurrentDomain.UnhandledException += ...;
AppDomain.CurrentDomain.FirstChanceException += ...;
You may also want to take the MEF approach. It is a framework for doing late loading/binding.
You might want to look at the details of LoadLibrary, GetProcAddress and Marshal.GetDelegateForFunctionPointer.
I would also build dll for testing locally, with the same interface as your external dll. How much functionality yo put in there depends on the complexity of the interface and your SimpleProgram.
There were some excellent answers to my old question about importing external dlls.
Uhhhh, what are you going to do about testing it? Assuming you've figured that out you need to make sure that either the .dll is in the GAC and reference it that way (ideally) or the .dll needs to be in the same place on all computers. Add the .dll in your references and mark it as Copy Local: false, so you don't deploy it. Good luck.

workaround needed: notify a user that exe is missing dependencies from within the application?

I wrote a quick console application that uses SharePoint dll files. If I attempt to run it on a machine that doesn't have said dll files, the application immediately crashes upon opening.
I'm definitely a newbie, but I would prefer if there was a way the application could tell the user they are using it on a wrong machine, before it hard crashed. Is there a way of doing this other than writing a second application to scan for dependencies, to be run prior to the application in question? If I put the code that needs dependencies in a separate class, that isn't instantiated until the application has checked it is on the correct computer, will the application still fail immediately on opening? Surely someone has figured out a workaround for this sort of situation.
Unfortunately you will have to write a launcher application - if you think about it, the required DLLs need to be there for the main application to even start. If you embed the scan in your main application, it will not start due to the missing DLLs.
You may be able to use a plugin architecture that scans for required DLLs and loads them dynamically (MEF comes to mind).
How about wrapping the load of that dll into:
try {
Assembly.Load(..);
}
catch(TypeLoadException ex) {
//Let the user know which type from what dll was not loaded.
}
You will have to load that dll at runtime to actually do that though.
It might be possible to copy the assemblies to the output directory for sharepoint. So references are made locally.
if your application references directly the SharePoint dlls or assemblies there is no way to notify the user because the .NET CLR will not execute your code if any of the statically linked needed assemblies is not available.
you can either use some kind of dynamic loading of the SharePoint assembly and types so at the startup time the application does not need that assembly to execute, or you create a launcher for your application which does the check and if all is ok starts your application otherwise notifies the user.

AppDomains and licence files

We have a dll which uses a third party component, with embedded licence file (licx). now we are trying to use our dll in a windows service applicaiton, using mulitple appdomains. the code get compiled. but when im running it im getting an error message, saying cannot find the runtime licence.
could someone explain me this. when use the dll in a single domain it works fine. please help.
Thanks.
How are you creating the AppDomain? There is a LicenseFile on AppDomainSetup; are you setting this? I'm not 100% "up" on license files and their use within AppDomains, but that may help a little...
Unfortunately information on this area (license files vs embedded) looks very sparse... you could try copying the embedded resource to a temp file?
If there is some static method/property to set then it is likely that you will have to do this per app domain.
I was under the impression however that licx files were only compiled into the executable project not into dll's.
Thus is your service is being started via a route that is not using the executable which had the license embedded in it then it will not get licensed. If you run the service but do not create multiple app domain's what happens?

Categories