Wixsharp: How to make a WixSharp installation to remove previous versions of the product installed with InstallShield

Created on 13 Apr 2018  路  7Comments  路  Source: oleg-shilo/wixsharp

Dear Oleg
I created a package with WixSharp to install my product and I used the following code to make sure that at each installation the previous version of the product is uninstalled:

   new ManagedProject("Product" ,
   .........
   project.GUID = new Guid("<my_project_guid>");
    project.ProductId = Guid.NewGuid(); 
    project.UpgradeCode = new Guid("<upgrade_guid>");
    project.Version = new Version("1.5.7.423");
    project.MajorUpgradeStrategy = MajorUpgradeStrategy.Default;
    project.MajorUpgradeStrategy.RemoveExistingProductAfter = Step.InstallInitialize;

everything works fine if I install my product with the package created with WixSharp: increasing the version the installation remove the previous version.

Before using WixSharp the installation was made by InstallShield and if I try to install my product on a machine where the previous version was installed by InstallShield that version is not removed.

The product name and the upgrade GUID are the same. Is there any other thing that I have to check?

thanks in advance

question

Most helpful comment

I was struggling with same issue for couple hours now. The gotcha was following:

When your update is going to remove a previous version of your software, such as
during a major upgrade, Windows searches the registry to find information about the
previous product such as its ProductCode property, and the location of its features
and components. If your original install was installed as per-machine, meaning not for
a specific user, then your update will have to do the same. Otherwise, the installer
may look in the wrong section of the registry, the part belonging to the current user,
and not find the product.

So the only missing thing in my wixsharp project was to explicitly set InstallScope property to InstallScope.perMachine as was in my older, non-wixsharp solution.

All 7 comments

Is there any other thing that I have to check?

No, this is exactly what I would do as well.

Though instead of relying on C#/WixSharp/WiX authoring technique I would use Orca to load both msi files (built by WixSharp and InstallShield) and verify that the acual binaries have matching GUIDs.

And another point that I don't remember from the top of my head but it is rather critical.
Somehow I have the feeling that being upgradable is not a backwards compatible property.

What I mean is that if you want upgrade the installed product v1.0.0 with v1.0.1 it is v1.0.0 that had to be already built with MajorUpgradeStrategy enabled. Thus if InstallShield didn't enable upgrading you may be out of luck.

You can test this with the MajorUpgrade samples.
I mean that if you build WixSharp msi v1.0.0 without upgrading enabled you may also have difficulties upgrading it to v1.0.1.

Dear Oleg
thanks very much for your reply. I checked the GUID with a powershell script which retreive them and the thay are the same. Maybe as you stated the InstallShield project was not compiled with the correct MajorUpgradeStrategy.

I solved the issue in my code inside the initialization of the embedded UI before the msi installation starts. I used the following code:
C# using Microsoft.Deployment.WindowsInstaller; Installer.ConfigureProduct("{MY-PRODUCT-GUID}", 0, InstallState.Absent, "");
which uninstall the previuos version with a specific GUID

Neat.
Though keep in mind that someone may try to execute your msi without UI ('/quiet') and then your routine will not be executed.

Thus if you want to avoid this and the UI for you the way to go in the pre-install (but non-UI) step you may fail the install if it is launched in quiet mode.

Dear Oleg
do you mean to attach the execution of this code in the Project.BeforeInstall event? I tried this way but the uninstallation of the old product doesn't success... maybe because another istance os msi is working?

Not exactly.

What I meant is - keep your solution as is ("inside the initialization of the embedded UI"). Full stop.

Now, if someone executes your msi with /quiet switch your embedded UI will not be initialized and the intended behavior will not be achieved. Meaning that you need to have an additional step to ensure that your msi is always executed with UI visible so your "uninstall older version" routine is executed.

How to ensure this? You can add Project.BeforeInstall event handler where you check the UILevel value. If it is "quiet" then you fail the installation with the error message "Please install the product by double-clicking".

It's just about handling the exceptional flow. That's it. But your original solution stays the same.

That's a great solution... thanks Oleg

I was struggling with same issue for couple hours now. The gotcha was following:

When your update is going to remove a previous version of your software, such as
during a major upgrade, Windows searches the registry to find information about the
previous product such as its ProductCode property, and the location of its features
and components. If your original install was installed as per-machine, meaning not for
a specific user, then your update will have to do the same. Otherwise, the installer
may look in the wrong section of the registry, the part belonging to the current user,
and not find the product.

So the only missing thing in my wixsharp project was to explicitly set InstallScope property to InstallScope.perMachine as was in my older, non-wixsharp solution.

Was this page helpful?
0 / 5 - 0 ratings