How to deploy multiple programs referencing one DLL? - c#

We have many projects using interop & related DLL. All projects have individual DLL reference with setup, but basically all of them use same DLL. So that's creates problem many times if any DLL register/unregister while installation/unistallation of setup.
Also, above approach can create problem if setup location changed or DLL reference location changed.
We need to place DLL at one location and all projects require to use DLL reference from that location to avoid register/unregister problem. But wondering about how actual reference located in .net for dependencies.
How can we do that? Any better solution or workaround for that?

Personally I like to make all my applications include all the DLLs referenced for a couple of reasons:
I can do a clean install and uninstall to remove all traces of my application without worrying about breaking anything
If I make a change to the shared DLL i don't have to worry about breaking other applications
But if you really need one location, you can register the DLL in the Global assembly cache. If you use a deployment tool like Wix this is pretty straightforward. Alternatively you could use a custom action to do the registration in the GAC

Put the assembly/interop dll into the Global Assembly Cache (GAC).
References:
How to deploy unmanaged dll into GAC
http://blogs.msdn.com/yizhang/archive/2007/06/17/how-to-deploy-unmanaged-dll-into-gac.aspx
Global Assembly Cache
http://msdn.microsoft.com/en-us/library/yf1d93sz.aspx

Use Merge modules: Merge modules provide a standard method by which developers deliver shared Windows Installer components and setup logic to their application. ...
This link might be helpful or just google for "visual studio setup project merge module".

Related

Loading C# DLL to C++/CLI - dependencies directory

I wrote a dll c++/cli library which uses my other c# dll library. C++/cli library works fine when I've got c# dll in the same folder as application which calls it. This library will be finally loaded to many applications and a C# dll must not be copied into directory with application. It has to be in the same folder as c++/cli library, but in that cases I've got System.IO.FileNotFoundException.
My suggestion is to load c# library manually or to change path where f.ex. firefox is looking for dependencies, but I tried with LoadLibrary() and Assembly::LoadFrom() methods to force loading from right directory. Of course I added directory path with dll to system PATH.
I work on VS2010.
You don't change the default directory where an application will look for dlls.
At design time put your dll in some well know location, the one you are going to deploy to. Add a reference to it, make sure it's set to Don't copy ever, otherwise it will end up in the bin folder. You have to do this otherwise it won't compile.
When you deploy, you'll need one package to deploy common dlls, and one for each application. Careful you don't create your own version of dll hell, if appA needs an older or new version of the common dll, compared to AppB
Add an AppDomain.AssemblyResolve event to main (for windows app). At run time the event handler will get fired when you reference a type in your dll, and the assembly has not yet been loaded.
In there you load it from the well known location. That usually in config, or in a relative path.
E.g.
AllMyApps
CommonDLLS
MyFirstApp
So the path you load the required common dll from would be "..\CommonDlls\MyCommondll.dll".
NB you will want to secure the dlls in some way, otherwise a bad guy might be able to inject their version of one in to your app, which would be bad...
You can use this mechanism to get the dll from a remote server or a database blob as well.
The simplest case is only a few lines of code, just look the event up. Took me about 15 minutes to get this going in a similar scenario.
Not on this machine though, otherwise I'd have pasted in the code.

Add projects in C# solution which belong to another solution

I have a solution which has a number of projects and each project refers to assemblies that are in a third party folder.
I now need to have access for debugging the code of those assemblies and fortunately I have to code.
I was wondering what the best way is to reference the code of the assemblies in my current solution?
Should I remove all my references to the assemblies (in third party folder) and then add the projects of those assemblies to my current solution or is there a better way? Although this gives me access to the code, the problem I see here is the assemblies were originally in a third party folder so I will need to make sure I have to switch back to the third party folder when I check my code back in.
There must be a better way than this?
You actually just need the corresponding pdb files of the third party DLLs.
The pdb file contains all necessary information. No need to remove the references.
It is not good idea to debug third party assemblies due to licensing restrictions. But if you want to do it, you only can remove references on dll's and add references to projects. You can automate your build to change references to dll's for release builds
You run your project while having reference to 3rdParty folder. Open those library code in seperate visual studio instance and use "attach to process" option in debug menu
Visit http://msdn.microsoft.com/en-us/library/c6wf8e4z(v=vs.100).aspx to know how to do this.
If you have the corresponding *.pdb file to the DLLs in question, you might getting away with just adding them to your solution. They need, of course, to be copied into the same location as their DLL files.

How do I relocate assemblies from a deployment project without breaking application references?

I have recently refactored a lot of my applications existing code and I am now looking at tidying up the deployment side of things.
The existing installer application installs everything in the application folder (with the exclusion of a couple of config files which are located in a sub folder). However, I have multiple applications which all use some common assemblies and my goal is to relocate these particular assemblies to the "Common Files" folder in the program files directory.
NB: I have read a lot about the GAC but I have no experience with it and also read a few horror stories, so trying to get a simple solution for the time being.
I managed to get the assemblies installed into the Common Files folder, however, as a result (typical I.T.) I have broken my app! If I copy the assemblies back into the application folder it works fine so the problem is obviously to do with how my app is referencing the assemblies.
To get the installer to install the assemblies into the Common Files folder I just updated the Folder property of each assembly in the Detected Dependencies list. My thoughts were when I did that the installer would somehow update my application to tell it to look in that folder for them but that doens't appear to be the case.
What exactly am I doing wrong here?
There should be no requirements for assemblies to be in the GAC, unless the developer of an application/library designed it so. You have the choice to write you application so that most (if not all) referenced assemblies load from a specified (Common Files) location.
Here's an example architecture that implements the technologies described in the MSDN articles referenced at the bottom of this response.
Example: In an SOA application you might have a couple of different (Windows) services. Services could be load balanced across multiple servers. Within each server, services can be installed under a 'Services' directory. Services living in the 'Services' directory could share assemblies from a (Common Files) 'lib' directory:
\CompanyName
\Services
\Service1
\Service2
\Service3
\lib
Every actual service would derive from a Base Service class that would make use of an Assembly Utility. Your Assembly Utility could be configured to search for assemblies in a systematic way, allowing you to use shared/common assemblies. The neat thing is that your application could run with local assemblies (in local development) but use shared assemblies when deployed.
In my real world example, I had the luxury of having custom build and deployment scripts. Think of the different scenarios you can have deploying 1 of N services. Do you always update the (Common Files) 'lib' directory? Can a service run with local assemblies different than the 'lib' assemblies? Etc.
I hope this was helpful. If your issue is getting a third-party installer to deploy your application correctly, then disregard and name the installer. Otherwise, the given example/solution should help :o)
Read on the subject at MSDN:
Programming With Application Domains and Assemblies
Resolving Assembly Loads
ResolveEventHandler Delegate
PS: I've had challenges resolving assemblies for Microsoft's Unity framework.
If you wish to "reference" some assemblies from common folder, it is possible at development time. However when deploying every application has to have those individual assemblies installed with them.
If at run time, more than one of your applications are sharing some assemblies then "that common folder" is GAC.

How to merge all dlls into one for an application?

My case: I have an app.exe and several dlls for it -- a.dll, b.dll, c.dll, etc (they come from single VS solution which consists of many projects). I would like to merge (ilmerge) all dlls into one so I would have: app.exe + x.dll.
Now, there is a problem -- the application expects to have all dlls so when I put just single file x.dll it won't run. So how to "redirect" application to use one x.dll -- is it possible at all?
The one solution I am aware is deleting all references to projects in Visual Studio and add instead reference to merged dll. But this would disable dependency chaining while recompiling solution.
Btw. I cannot merge exe and dlls together because this is a wpf app, and ilmerge cannot handle it.
You could instead of creating 3 DLLs you could create 3 .NetModules and turn them into one DLL. It would require some editing of the actual CSPROJ files because creating .NetModules is not currently integrated into the MSBuild system, but it can be done.
You can think of a .NetModule as a kind of static library in C/C++. Of course there are differences but overall the concept is similar. They are most common when trying to make a single DLL containing multiple .NET languages, but they will work for you as well. Check them out here.
I'll recommend if you read this blog. Its an alternative to ILMerge when you need to merge WPF assemblies.
http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx

Team Foundation Server - Add rereference to existing dll to a new class library project

I've just started using Team Foundation Server and have added a new Solution that contains a project of type class library. I need to add a reference to the new class library project to an existing class library (dll) that we have created. What is the best way to do this? I've noticed that if I try to add it from the original location as an existing dll, it keeps the original location of the dll. I think what I want is to actually copy the dll to the new project, and add a reference to it locally - but I can't figure out how to do that.
Write a MSbuild/Nant script that build's and copies the dll to a common lib directory. Then reference the lib\foo.dll in 2nd project. Also create the build order.
Can you include both the old and new projects in the same solution? If so, you can reference the project directly (primary artifact) instead of the .dll output (secondary output). This 'just works' when you need to build multiple configurations, such as debug, release, etc.
If that dll is something that will be shared among different libraries and applications, you may want to consider putting it in the GAC. This will also help avoid versioning issues of putting it in a common lib directory (although you could just put folders in the common lib directory for different versions)
MSDN article on the GAC: http://msdn.microsoft.com/en-us/library/yf1d93sz.aspx
Another way that doesn't involve copying the whole project or messing with the GAC would be to:
Add a reference to the DLL to your project
Open the references folder in your project
Right click the DLL -> Properties
Find Copy Local and set it to "True"

Categories