How to move user content in Wix Installer - wix

To support Window Vista in my game, I have changed were the save files are placed (From under Program Files to My Documents) for both XP and Vista installations.
Now I would like to be able to move the current XP users save games from the old location to the new location.
I think I can correctly trigger this via the upgrade checking code like so:
<Upgrade Id="PLACE-GUID-HERE">
<UpgradeVersion OnlyDetect="yes" Minimum="$(var.ProductVersion)" IncludeMinimum="no" Property="NEWERVERSIONDETECTED" />
<UpgradeVersion OnlyDetect="no" Minimum="1.1.0" IncludeMinimum="yes" Maximum="$(var.ProductVersion)" IncludeMaximum="no" Property="OLDERVERSIONBEINGUPGRADED" />
<UpgradeVersion OnlyDetect="no" Maximum="1.1.0" IncludeMaximum="no" Property="MOVESAVEFILESUPGRADED" />
</Upgrade>
where 1.0.x was the old way and 1.1.x will be the new way, thus I could do something in a custom action based on MOVESAVEFILESUPGRADED, but the heart of the problem, I cant see how to move non-installed files from one location to another.

Use the CopyFile element. A custom action is overkill and VBScript custom actions are unreliable. See http://www.joyofsetup.com/2007/06/07/when-vbscript-and-jscript-custom-actions-are-even-more-evil/.

I dont think there is a built in custom action that will do that.If you write your own its best to use a dll, but vbscript or bat file will also do the job.
This might help

Related

Wix Not showing Repair Option in UI

I implemented upgrade handlers and downgrade prevention
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion OnlyDetect="no" Minimum="$(var.MinimumUpgradeVersion)" Maximum="$(var.ProductVersion)" IncludeMinimum="yes" IncludeMaximum="no" Property="PREVIOUSVERSIONINSTALLED" MigrateFeatures="yes" />
<UpgradeVersion OnlyDetect="yes" Minimum="$(var.ProductVersion)" IncludeMinimum="no" Property="NEWERVERSIONINSTALLED" />
</Upgrade>
And further on
<Custom Action="PreventDowngrading" After="FindRelatedProducts">NEWERVERSIONINSTALLED AND NOT Installed</Custom>
<RemoveExistingProducts After="InstallInitialize">PREVIOUSVERSIONINSTALLED</RemoveExistingProducts>
However, now when I try to double-click my MSI to do a repair the UI doesn't appear anymore. I am using the same Upgrade Code so Wix should automatically allow me to repair.
Any ideas?
To do a major upgrade it might be better to use the majorupgrade element to make sure that you've included everything required. That's assuming you want a major upgrade, and I can't tell.
You are misunderstanding something. You (in WiX) use the majorupgrade element when you have a new version of your product that will replace the older one, and that includes a new ProductCode and the same UpgradeCode. This is nothing to do with repair. A repair is one of the options that can be available when you try to modify the existing installed product as defined by ProductCode, not UpgradeCode. A repair is not an upgrade or any kind of update. It repairs the existing product and will require the same MSI file that the product was originally installed from. The same UpgradeCode is nothing to do with repair.
What GUI are you including? See an online tutorial here: http://wix.tramontana.co.hu/tutorial/user-interface/ui-wizardry
Are you setting the ARPNOREPAIR property? Check in the registry at the following location (subkey, check for DWORD NoRepair):
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

Configure WiX project to install multiple versions, but remove same minor version

I need to configure my WiX project to be able to install multiple minor versions of the product. IE: I can have 1.0, 1.1 and 1.3 installed. If I try to install 1.2, it will work, but if I try it with 1.1, it will uninstall the previous 1.1 installation before proceeding.
So far, this is what I have in my Upgrade tag:
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Minimum="$(var.MajorMinorVersion)" IncludeMinimum="yes"
Maximum="$(var.VersionNumber)" IncludeMaximum="no" Property="OLDERMINORFOUND"/>
</Upgrade>
UpgradeCode is a guid defined in my wxi file and MajorMinorVersion is the same as VersionNumber, but with the build at 0 (1.1.0 when the version is 1.1.12).
I'm guessing that I have two possibilities:
I make another UpgradeVersion tag or update the current one to have the maximum at the next minor version and exclude it from the search:
<UpgradeVersion Minimum="$(var.MajorMinorVersion)" IncludeMinimum="yes"
Maximum="$(var.NextMinorVersion)" IncludeMaximum="no"/>
Using a custom action to set NextMinorVersion somehow. Maybe using a property instead.
Or, change the UpgradeCode manually each time the minor version changes. Or have the first few characters of the guid represent the version and the rest be unique? I doubt that's a good idea though...
So basically, what would be the best way to accomplish this, in the hopes of having only one setup project for all versions?
EDIT
I've looked into the MajorUpgrade tag, but I don't think I can configure it to have many minor versions at the same time. Any light on this is appreciated.
I've also looked into making a preprocessor extension that would manipulate the version number using functions, so I could do this:
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Property="OLDERMINORFOUND"
Minimum="$(var.MajorMinorVersion)" IncludeMinimum="yes"
Maximum="$(myprefix.NextMinor($(var.VersionNumber)))" IncludeMaximum="no"/>
</Upgrade>
See my answer for details.
So I wrote an extension as per the WiX manual (Part 1 and Part 2).
I made a preprocessor extension that takes a version number string (ex: 1.2.3.4) and manipulates the version by parsing and splitting the string.
So now I can write this in my .wxs file:
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Property="SAMEMINORFOUND" OnlyDetect="no"
Minimum="$(var.MajorMinorVersion).0" IncludeMinimum="yes"
Maximum="$(version.NextMinor($(var.VersionNumber)))" IncludeMaximum="no" />
<UpgradeVersion Property="OLDERVERSIONFOUND" OnlyDetect="yes"
Maximum="$(var.MajorMinorVersion).0" IncludeMaximum="no"/>
<UpgradeVersion Property="NEWERVERSIONFOUND" OnlyDetect="yes"
Minimum="$(version.NextMinor($(var.VersionNumber)))" IncludeMinimum="yes"/>
</Upgrade>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallValidate"/>
</InstallExecuteSequence>
Where version.NextMinor is a call to my preprocessor extension.
So my installer will only detect installations of the product unless the minor versions match, where it will be uninstalled.

I have installed major upgrade successfully but it also allowing another previous version install in wix

I have installed major upgrade (say #206) successfully and included code as in (#206):
<Upgrade Id="$(var.ProductUpgradeCode)">
<UpgradeVersion Minimum="$(var.ProductVersion)" IncludeMinimum="no" OnlyDetect="yes" Language="1033" Property="NEWPRODUCTFOUND" />
<UpgradeVersion Minimum="1.0.0.178" IncludeMinimum="yes" Maximum="$(var.ProductVersion)" IncludeMaximum="no" Language="1033" Property="UPGRADEFOUND" />
</Upgrade>
Scenario is:
I have installed build #177 then upgraded to build #206. It is still allowed to install #177 which I want to prevent this downgrade.
From build #178 onward I have changed product GUID for major upgrade and which is working fine.
Please suggest how to prevent this. I don't want to downgrade build below 177. If I have done major upgrade on build no <= 177.
Your problem is the how the comparison of versions is done in MSI by default - 1.0.0.123 is treated the same as e.g. 1.0.0.33. You either have to increase your revision version to make the installer detect this as an older version or use a workaround.
You might for instance create a custom action to check against this very Revision version and place it e.g. before InstallValidate:
<CustomAction Id='MyVersionCheck' Return='check' (...) />
<InstallExecuteSequence>
<Custom Action='MyVersionCheck' Before='InstallValidate' />
</InstallExecuteSequence>
Some more information can be found in this article, for informations about how to create custom actions i'd recommend this blog entry as a starting point.

Uninstalling another product during install using WiX

I want to be able to remove another application as part of the install of my MSI file. Currently, I have the following in WiX:
<Upgrade Id="{586A589B-D6D5-48D3-9B6D-571EF230ED6A}">
<UpgradeVersion Minimum="$(var.ProductVersion)"
Property="NEWERPRODUCTFOUND"
OnlyDetect="yes"
IncludeMinimum="yes" />
<UpgradeVersion Minimum="1.0.0"
Maximum="$(var.ProductVersion)"
Property="PREVIOUSVERSIONSINSTALLED"
IncludeMinimum="yes" />
</Upgrade>
<Upgrade Id="{71F6B5D5-8CB9-48C9-B359-4BA22D5ADAF3}">
<UpgradeVersion Minimum="1.0.0.0"
Maximum="3.5.3"
Property="OLDAPPFOUND"
IncludeMinimum="yes"
IncludeMaximum="yes"/>
</Upgrade>
The first upgrade section is what upgrades my current MSI file (and this works). The second part is what I am trying to use to remove the other application (and this doesn't). Both the current MSI file and the one I am trying to remove both install in the per-machine context, so I cannot understand why this doesn't work. How can this problem be fixed?
A verbose log file should indicate what products are being detected by the Upgrade elements. From there it should be possible to track down the bug in your authoring.

Uninstall shortcut in WiX when Product Id is * to allow major upgrades?

I was following the tutorial here to implement an uninstall shortcut in the start menu.
In short, the way to create the uninstall entry is as follows:
<Shortcut Id="UninstallProduct"
Name="Uninstall My Application"
Target="[SystemFolder]msiexec.exe"
Arguments="/x [ProductCode]"
Description="Uninstalls My Application" />
Based on Rob Mensching's suggestion here, if the application is small enough and you don't need to handle small updates and minor upgrades (which I don't), you can force every update to be a major upgrade. This is shown here. I used Rob's suggestion which was this:
<Product Id="*" UpgradeCode="PUT-GUID-HERE" Version="$(var.ProductVersion)">
<Upgrade Id="PUT-GUID-HERE">
<UpgradeVersion OnlyDetect="yes" Minimum="$(var.ProductVersion)" Property="NEWERVERSIONDETECTED" IncludeMinimum="no" />
<UpgradeVersion OnlyDetect="no" Maximum="$(var.ProductVersion)" Property="OLDERVERSIONBEINGUPGRADED" IncludeMaximum="no" />
</Upgrade>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>
Now my question is if Product Id is randomized (*) to allow a major upgrade to take place, is there any other way to add an uninstall shortcut to the start menu or must we do it through Add/Remove programs? I'd prefer to create the shortcut in the start menu since it's just easier for the user. Obviously the way it is now, it won't work because [ProductCode] that is used in the msiexec arguments will change on every install. Thanks.
Are you saying you've tried it and it doesn't work? How does it fail? What is the shortcut argument? Using Product/#Id="*" sets the ProductCode property, so it should work correctly.