I have two installers:
Installer A installs A.dll v1.0.0.0
Installer B updates A.dll to v2.0.0.0
When I uninstall B, it does not delete A.dll. There is still A.dll with version 2.0.0.0
A.dll (v2.0.0.0) can be removed only from installer A.
Installers have different UpgradeCode and Component Ids.
How can I remove the replaced content of a Product from installer B?
Files that are shared between two setups (file is installed to the same absolute path by both setups) must maintain a single, stable component GUID to allow Windows Installer reference counting to work correctly. The mechanism to achieve this in Windows Installer is a merge module. WiX features its own way to handle shared files with the WiX include file approach.
I wrote an answer a while back with more information on merge modules and WiX include files here: WiX 3.8: Two MSI using the same registry values. How to delete registry values only if both MSI are uninstalled?
If you need to use different versions of the dll with different applications, then they should be installed to a private location for each application and they should have different component GUIDs:
ProgramFilesFolder\MyCompanyFolder\MyApp1\MyExe.exe version 1.0.0
ProgramFilesFolder\MyCompanyFolder\MyApp1\MyDll.dll version 1.0.0
ProgramFilesFolder\MyCompanyFolder\MyApp1\MyExe.exe version 2.0.0
ProgramFilesFolder\MyCompanyFolder\MyApp2\MyDll.dll version 2.0.0
Alternatively you can install them to a shared location in separate folders and bind properly via your manifest:
CommonFilesFolder\MyCompanySharedFiles\1.0\MyExe.exe version 1.0.0
ProgramFilesFolder\MyCompanyFolder\MyApp1\MyDll.dll version 1.0.0
CommonFilesFolder\MyCompanySharedFiles\2.0\MyExe.exe version 2.0.0
ProgramFilesFolder\MyCompanyFolder\MyApp2\MyDll.dll version 2.0.0
CommonFilesFolder\MyCompanySharedFiles\2.5\MyExe.exe version 2.5.8
ProgramFilesFolder\MyCompanyFolder\MyApp2\MyDll.dll version 2.0.0
You can deploy the shared files with a separate MSI so they can be updated without recompiling your main MSI, or you can use a merge module to compile the shared files into your main MSI (sort of static linking).
Finally you can install the shared files to the GAC if they are .NET assemblies (but don't):
When and when-not to install into the GAC?
What are the advantages and disadvantages of using the GAC?
Or you can install native Win32 files to the WinSxS side-by-side folder. For native files you can also install shared in System32 or SysWOW64 or another non-side-by-side, but shared folder.
A similar answer here: Wix Toolset: How to restore replaced file on uninstall. Much more elaborate than the above description.
And here is a rather comprehensive (and verbose unfortunately) description of how Windows Installer component referencing really works: How exactly are files removed during MSI uninstall?
And finally an answer with some recommendations on how to improve and simplify WiX files by using default attributes and enabling automatic component GUID generation. Highly recommended for you to check out: Continue the Wix setup after having a service that could not start. Don't let the title confuse you, it is generic WiX advice. I particularly recommend looking at the automatic component GUID feature since it will help you do component GUID assignment correctly.
Related
Can a product installed by two different installers, if we keep same GUIDs and Paths for files,services, registries, upgrade codes? Install by installer1 and uninstalled by other installer2, or upgraded by installer2
I have a component, is bundled with two installers
One is bundled as MSM module in Installer with multiple other components.
And other I have standalone installer that installs my component, it does not have MSM module just has .wixproj and .wxs file.
So my question is can I have compatibility in between standalone installer and Bundled installer
(component installed by Standalone can upgraded by Bundled component installer and vice versa)
I know this can be done using shared MSM but trying to acomplomplish it with minimum changes just USE same GUIDs and PATHs.
Also how uninstallation will work, if uninstalled by Bundled installer, what will happen if uninstall triggered by
clicking "remove" standalone installer. also vice versa case "uninstalled by standalone installer and then tried to uninstall bundled uninstallation"
Please consider I have used common Filepaths and GUIDs for components. Is this sufficient? Consuming existing standalone installer.
I feel consuming same MSM in standalone installer may be longer path.
wanted to know is this possible? if yes what additional steps I have to perform.
Background
WiX & the Windows Installer are completely new to me.
In production, we used an MSI (created using WiX) to install our software. The MSI references a third-party assembly (e.g. OtherCompany.ThirdParty.dll, version 2.5).
The next release of our software must reference an older version of the third-party assembly (e.g. OtherCompany.ThirdParty.dll, version 1.7).
While I understand that installing an older version of a dependency is uncommon, it must happen.
So my question is... how do you configure a MSI (generated by WiX) to use an older version of an assembly without having to completely uninstall the existing package?
Options
We have explored the following:
Increment the assembly's version
it's a third party assembly, and
for traceability this is not an option
rename the assembly
the dependency is being retrieved using NuGet... so this won't be straight forward
force existing install to be completely removed (automatically or manually)
we don't want configuration information that was collected during the previous installation to be lost, so this isn't an option
schedule RemoveExistingProducts before costing
not recommended by Microsoft (see: MSDN)
custom action: to delete dependency
if the installation fails, the application may be left in an undefined state
override file version in setup
moving forward, this will be error prone
changing the REINSTALLMODE
From the articles that I have read, it appears that this should only be used as a last resort.
use a WIX companion file
am still investigating
For Moderators
I am aware that there are other SO posts on this subject. Please note that several of the recommended solutions are incomplete or are error prone.
References
MSDN: Patching and Upgrades
MSDN: RemoveExistingProducts Action
downgrade a library during a msi upgrade
Why Windows Installer removes files during a major upgrade if they go backwards in version numbers
MSI Writing Guidelines
What Every Developer Should Know About MSI Components
Windows installer deletes versioned file during product upgrade, instead of downgrading it
MSDN: Windows Installer - File Versioning Rules
Msiexec REINSTALL=ALL REINSTALLMODE=vamus not reinstalling anything
good overview of what is happening under-the-hood
Forcing an upgrade of a file that is modified during its initial installation
this is an older post is from 2009
Some issues are best solved by the application design rather the deployment.
There are two places to save a particular version of a .NET assembly: the GAC or the application folder (or subfolder with probing privatePath). In either case, you might want to use a bindingRedirect.
Also, you can load from a specific location using AppDomain.AssemblyResolve, provided the binding is not successful using the GAC.
General Reference: How the Runtime Locates Assemblies—thanks to #Pressacco.
I am building a MSI installer using WiX. As the product that is supposed to be installed requires a VC++ runtime I found the two option of doing that which are (a) using the corresponding merge module and (b) using burn to run vcredist prior to the actual product's MSI. To differ between those two options I have some questions I didn't find the information on.
1) If using the merge module the runtime is not installed separately (no entry in add and remove programs) but as far as I understand just copies the required files to their corresponding locations.
1.1) If there already is an installation of vcredist present on the system I suppose the merge module does nothing during the product's installation?
1.2) If there was a vcredist installation present as mentioned in 1.1) what happens if the user just uninstalls that runtime via add and remove programs? I suppose the product does not work anymore (at least until a repair installation is performed which causes the merge module stuff in the MSI to re-add the necessary files?)
1.3) If the vcredist was not yet installed and the MSI installer copies the files to the system and after that another installer or the user is calling the vcredist.exe what is happening then? Does vcredist reports the runtime as already being installed?
1.4) If uninstalling the product are the files copied to the system via the merge module being removed?
1.5) If the answer to 1.4) yes (VC++ runtime files are removed): If there are two different products are installed on the system both using the same merge module internally and one of the two products is uninstalled what happens to the installed runtime files? Are they removed and the other product is not working anymore due to the missing runtime files?
Thanks in advance for your help and information.
Regards,
Gunnar
A merge module is just a consistent way to install (usually shared) files properly by including them in a build. As an analogy, the C++ compilers build .obj files that are combined into an exe, but you can no longer talk about an obj having a separate existence after the exe is built and running. It's the same with merge modules. Once they are in the MSI they are just files to install, and they follow the standard rules. If a file is already installed (in the shared location) it will be overwritten if the incoming version is higher than the already installed version. Its containing component will be ref counted up by one, and uninstalling other products (including the VC redist) using the component will ref count down so that any products using the file don't break - there is still a version for them to use.This is just the standard sharing method for files shared amongst products, and it makes no difference that one product is a VC redist and the other is your MSI. It could just as easily be several of your products that each install the files using merge modules and each can be uninstalled without breaking the others because of the ref counting and that fact that the shared location and common component ID makes the sharing work as intended. So forget that one product is the VC redist and the other is yours (or another that uses the same files) - it's all just the Windows Installer's shared file/ref counting mechanism.
This is for the recent merge modules that install the files to the system folder. There have been other schemes using WinSxS and policy redirects that don't seem to be used now (VS 2015).
I'd like to create an installer package to install registration-free COM components (with manifest files included). This would be more or less a self-extracting archive to place some files in a target directory given as commandline argument, but it would also need to check or install some other redistributables like VC++ or DirectX.
The package is supposed to be used in another applications's installer as some kind of redistributable package itself. It should not be registered in the "Program and Features" dialog of Windows but has to be removed with the application. Ideally there should be no changes to the Windows registry.
So far I haven't been very successful. Can anyone please provide me with some hints regarding this use case?
You've got about a dozen different questions in that one question. Start with just creating a simple MSI that successfully installs your files and your manifest. Create a COM client to test it. You can also put AppSearch and LaunchConditions in your MSI to detect your dependencies and not allow installation if they are missing.
That's about all you should have to do for this simple question. As for the other questions.... if you are a redistributable and someone else is silently installing you then it's their job to handle the installation of the other redistributables. Also if they don't want you listed in Programs and Features they can pass the ARPSYSTEMCOMPONENT=1 to your installer and you won't be listed. If they want to uninstall you when they uninstall themselves, that's their problem not yours.
If you are really creating a redistributable to be used by other products, sometimes a merge module is the appropriate solution. They build their MSI files and include your merge module.
Otherwise, reg-free COM is in theory an easy install because you're just installing manifest files and Dlls etc. However I don't understand how that could be used by other apps because (IIRC) a client app exe needs your manifest and Dll in their install folder, so how can they do that when they are not installed yet? Or even if they are installed how can you find them? So that goes back to the merge module idea so they include your merge module and install an exe, your manifest and your Dll in the same location. When they uninstall so do your files.
When my file set includes DLLs with one ore more dependencies to the C++ run-time DLLs I need to install the file from VCRedist.exe. This can be difficult, since each DLL is dependent on a specific version of the C++ run-time.
How do I add automatically the run-time redistributables to my installer?
How do I handle DLLs that require different versions of the C++ run-time in the WinSxS?
You need to install the latest version (highest) version required by your libraries and a policy file that redirects older versions to the new version.
You can do both with merge modules installed with Visual Studio. They're usually located in C:\Program Files\Common Files\Merge Modules. See MergeRef element and an example how to install Visual C++ redistributable with your installer. You will also need to add a policy merge module to your install.
You can simple make sure the latest vcredist is installed, it automatically includes support for older versions.
I think the easiest it to use bootstrapper to install the runtime before your installer runs. You might need to create your own package, but it is easy to use Bootstrapper Manifest Generator for this.
In the product.xml you can add an installation check to make sure it is not installed twice, for example:
<InstallChecks>
<MsiProductCheck Property="VCRedistInstalled" Product="{1F1C2DFC-2D24-3E06-BCB8-725134ADF989}"/>
</InstallChecks>
See here for other GUIDs.
Neither heat nor Votive does support the requested feature. The run-time DLLs must be added manually.