I currently on a project which will be used by a handful of other project. The project contains:
I would like to provide separate installer for this project and other projects would detect if it is installed and use it if available.
What would be the best way to handle this ?
I have considered:
I have technical difficulty with #2, how would other projects use my dll? I rather avoid reflection. If I gac the dlls, how would my managed dlls find the native dlls?
EDIT: I'm not looking for specific packager/installer with specific feature. I'm simply asking what is the best practice conceptually.
I've never actually used merge modules before so I thought I'd have a play and see how they worked.
A merge module allows you to package up common installer functionality into a re-usable module (typically installation components, but possibly also some setup UI). Each application installer that uses this merge module is free to install these components wherever they want (for example alongside their application) and if they do multiple copies of these components will be installed, however if they are disciplined and all specify the same install location then only one copy of the components will be installed.
If the components are installed to a common location then things work quite nicely in that the components are only uninstalled once all the dependent installers have been uninstalled. This is far simpler than having a separate installer for the common components as it means that each application installer doesn't need to worry about whether or not it should uninstall this common installer when being uninstalled (which could potentially break all other applications which use these components).
The tricky thing about this whole arrangement however is versioning - if App A installs CommonLib v1.0 and then App B installs CommonLib v1.1, what should happen?
If multiple directories are used to separate versions then you should make sure that it is the merge module that decides the names of these directories, for example the directory structure of your common library might look like this:
Program Files
Common Lib // This is the folder that installers must specify
*Common data files*
v1.0
*v1.0 Files*
v1.1
*v1.1 Files*
This way even if an application installs v1.1 while accidentally leaving the common installation directory unchanged, it won't overwrite the v1.0 files.
(Note that there might be other more sophisticated ways of having the merge module specify the installation location, but I know that the above works so I didn't look into it too much as it probably depends on what you use to create your MSI - Wix / InstallShield etc...)
Also if you separate out your versions into different directories you will also need some mechanism to allow either your library or the end user Application identify where the the relevant files have been installed to (for example a registry key) - this is where installing to the GAC (or maybe just installing the managed library alongside the application) has its advantages as it means that this logic can be embedded into the library itself.
Ultimately how you do this will depend on your specific requirements, but I hope that this has at least given you some ideas.