WiX - Cancel upgrade if previous version is not same configuration (Debug/Release) - visual-studio

I'm having some issues with custom actions not working properly (and causing broken installations) when trying to install a Debug build on top of a Release build, or vice-versa. Therefore I'd like to prevent such upgrades completely, and force the user to manually uninstall first.
So far I have this:
<?if $(var.Configuration) = Debug?>
<?define DisallowUpgrade = "yes"?>
<?else?>
<?define DisallowUpgrade = "no"?>
<?endif?>
<MajorUpgrade Disallow="$(var.DisallowUpgrade)" ... />
This forces the user to always uninstall first when installing a Debug build (which is fine). However it does not stop a Release build from trying to upgrade over a Debug build. How can I do this?
Thanks!
P.S. As I was typing I just thought of increasing the version number for Debug builds -- say by adding 100 to it. This would work, but could lead to confusion with QA people, so I'd prefer a cleaner way.

Why would a "user" ever know what a debug / release build is? IMO a user should only ever see a release build.
I would suggest build debug MSI and release MSI as two different products (upgrade code and even destination directory if you want side by side installs ) and a debug can only upgrade a debug and a release can only upgrade a release and only release MSIs ever go out the door to customers.
And of course, the less custom actions the better. :)

Write $(var.Configuration) to the registry, use RegistrySearch to load it, and use Condition to compare what's in the registry with the current value of $(var.Configuration).

Related

Patching an installation using a bundle oder msi?

I have no experience in patching/upgrading an installation.
We have a wix bundle setup with a standard (wix-created) msi inside which is added to the bundle this way:
<MsiPackage SourceFile="MySetup.msi" Id="MySetupId" Cache="yes" DisplayInternalUI="no" SuppressSignatureVerification ="yes" Visible="no" >
so in Add/Remove software section there is the bundle shown, not the msi itself.
Both, the msi and the bundle, are signed.
Currently our released version is "2.1.0.BuildNumber".
The bundle.wxs has upgrade code A
The msi has product code B and upgrade code C.
Unfortunately this version contains a mean bug but we don't want to release "v2.2.0.BuildNumber" just because of this bug, but "2.1.1.BuildNumber", so we need a patch.
What is be best practise here? Should we just create a msp file described like here
http://wixtoolset.org/documentation/manual/v3/patching/wix_patching.html?
Will this break the relationship between the bundle and the msi? Will this patch be shown in Add/Remove programms section?
Or is there a possibility to use the bundle for a patch?
Goal is, that our customers just can install the patch without deinstalling the old version, but can deinstall the whole scope using the formerly released bundle.
My personal advice is do not create patches unless absolutely necessary. You avoid a lot of trouble. The main problem IMO is that patches do not fit well onto source control and CI. First, you are not able to automatically increase the build number and include it into version number - it must remain the same. Second, creating an msp patch requires the binaries from the previous build be present during the new build. In MS technology the previous msi should be present, in WiX technology you cited you will need *.wixpdb from the previous build. Third (or the first?), the patch is a one-time action which should not be automated for continuous execution by CI.
If the bundle does not include its packages into exe but download them, a new bundle version can download only changed packages so that installation time will be small. Otherwise you are out of luck.
You need to create an msp upgrade for your buggy msi. The upgrade may or may not change the msi version, but if it does then the version of msi will not match the version of the bundle. User does not see msi version anyway.
You can install msp directly. When the bundle is uninstalled, msp will be uninstalled too. I do not know whether the msp will be visible in ARP (msi is not visible).
You may create a patch bundle. This is an independent bundle with its own upgrade code. It will contain
<Bundle .... ParentName="Name of your main bundle"...>
<RelatedBundle Id="YourMainBundleUpgradeCode" Action="Patch" />
Include MspPackage with your msp into the Chain.
This bundle will be visible in Installed Updates as a child of "Name of your main bundle" and it will be uninstalled with the main bundle or when a new version of the main bundle is installed.
You will also need to include a Condition to prevent installation of patch bundle when the main bundle of this particular version is not installed. There is no documented API to detect bundles (although you may use a RegistrySearch), but you may do ProductSearch for particular version of your msi included in main bundle.
Note that a new release of the main bundle with the same version number will install in parallel (there will be two identical entries in ARP) and new release with greater version number will automatically uninstall previous release. Thus, you cannot make new release of the main bundle.

VS 2015 Installer project - Dependencies with older version Number than installed

I have an app that uses a VS 2015 installer project.
Our BONEHEAD vendor, ComponentOne, released a new version of several assemblies upon which my product depends.
Here's the rub:
Old DLL version: 4.1.20102...
New DLL Version: 4.0.20162...
The newer DLL at least have newer file dates than the older one.
Of course, the newer DLL fix real user problems brought about by the bugs in the C1 components since corrected.
While I can get to the correct DLL by having the end user fully uninstall the older version of my product and installing the newer version, this is unworkable because:
We have an auto-update function that phones home and checks for the latest patch and installs it to update prevoius version; and
Our customers are female, 60+ and cyberphobic.
The project already has the RemovePreviousVersions property set to true, and I was hoping that this did a complete uninstall silently. It does not; the six assemblies with the version error are not replaced. The DetectNewerInstalledVersion property is also set to true; I tried to install with False, and it has no effect.
I also tried to explicitly include all detected dependencies of the C1 assemblies and it has no effect.
Is there a way to force the install project to overwrite the assemblies as long as the file date is newer regardless of the wrongly-encoded version?
Edited to add the following:
I tried making a custom action to delete the offending assemblies before installing anything - it runs after the files are installed. :(
I tried InstallShield LE, only to find out that it could not discover the dependencies more than one level deep, and provided no convenient way to explicitly specify the dependencies. I also could find nothing that would let me say to overwrite the assemblies based on date or unconditionally.
Thanks for any help you can offer!
I found an effective workaround.
I already had RemovePreviousVersions set to true, so I changed the application's default folder by adding [ProductVersion] onto the end of the path.
What this accomplished was:
It deleted the old assemblies; and
It created the new assemblies in the new folder.
This solved the problem nicely. No setting REINSTALLMODE to amus; no brute force solutions.

Program updating does not works properly

I have a program which has several versions. In the last version I have a problem: when I'm trying to update previous version to new one, the installer of new version removes files from previous version, but don't installs new files.
Just installing works fine, but updating process has this problem.
What can be the reason of this problem ?
Upade: I'll try to describe more detail
I have VS project where I have a project of program and an installer of this project. Till present all were working fine, but after my last big update ,the installer start work incorrectly.
And another question:
How I can debug installation process ?
I dont know which program you have. Generally programs have problems because of multible versions, because programmers arrange this. For example ;
Lets consider Microsoft Framework. If you have 4.5 you cannot install 4.0, so that with similar idea you cannot update it.
Try to delete other versions and update them and install others. Or you can also stop services which you dont want to update.Then other one will be updated without any problem.

Detemining newer version of executable in Wix

We have a software that has couple of executables inside. One of the executables is Windows service, and it doesn't change that often, usually we release many updates to the main executable, but the service version is same inside installer.
When service is installed first time or upgraded with newer version, we need to run custom action. We managed to solve first install part, but we don't know how to determine that version we're installing now is newer than one that already exists. Sort of if(newver > oldver) run custom action.
Thank you in advance
- Jack
You can try using the upgrade rules of your package. More details here: How to implement WiX installer upgrade?
Rob Mensching (the second answer in the linked thread) shows an example for upgrade rules. You should first familiarize yourself with the Upgrade table and how upgrade rules work. There isn't an easy answer or a quick fix for this in WiX.
Basically, you should have 2 upgrade rules
the first sets a property when an older version is found
the second sets another property when a newer version is found
After that you can use the older versions property to condition your custom action. For example, if the property is named OLDERVERSIONFOUND the custom action condition can be:
OLDERVERSIONFOUND
or something like
OLDERVERSIONFOUND > "1.0.0"
Your best bet is to store the "service" version somewhere in the registry, search for that registry value during upgrade and run your CA if newver > oldver (and the CA should also update said registry value to newver)
Note that Custom Actions are (generally) an admission of failure. I always try to separate out the configuration portion of setup to a pre-install (for sysadmins doing deployment) or post-install (for interactive installations) step - often a separate executable.
Declarative installations with no custom actions are much more reliable - if you can figure out how to rewrite the service so that your custom action is no longer required, you'll be much better off in the long term (this doesn't help when you're under pressure to release now, but it's something to think of for future releases)

Make Visual Studio not care about DLL versions

Is there a way to make visual studio not care about dll versions? Is this a bad idea?
I am resetting up my dev machine and I just installed the latest version of Pex and Moles (version .92). All my projects are on version .91.
We are in the middle of a release and don't want to upgrade right now. Also, I cannot find an installer to version .91.
When I try to compile I get a message that I am missing the reference. (Hence this question)
The version is important.. By definition, there is a difference from each released version to the next (or there would be no need for a new version). Your program may not perform correctly if you are expecting one version and instead have another.
This was a part of what was known as "DLL Hell" in the pre-.NET days... If you needed to use a third party component (Crystal Reports Viewer is one we always had to deal with), you would just use the reference to whatever installed version was on the user's PC. Our retail locations had to have a specific version of Crystal Reports for their bookwork reports to print correctly, and because of that, we had to hold on to an old version forever.. Upgrading Crystal on the PC broke the vendor's bookwork app. On my first ever PC, I had several applications break when I would install or upgrade another. In particular, Real Player broke my telephone answering machine software. Goofy stuff like that...
So, the version IS important, even if it is an annoyance. It's also why I have a bias against third party tools that I have no code for, and can't recompile myself.
If you look at the properties of a referenced DLL, you will see a property "Specific Version". If you set it false, it doesn't track the specific version in the project file.
For this to work, you have to somehow fix the references where ever they are used. You can do this by opening every solution and fixing the references (at which time you could also just update the references to the correct version, paying heed to David's comments).
If you have a lot of solutions, you might use a tool like sed (see this post for windows versions of tool like this Is there any sed like utility for cmd.exe) to just update the project files as needed all at once.

Resources