I've upgraded an old Wix based installer that has both an MSI generating project and a bootstrapper project (in Visual Studio). The bootstrapper sequences the MSI with a check for .Net pre-requisite/download. The new Wix# project just produces an MSI and it is installing and working just fine other than I cannot get it to replace the older installs. I've set the new project UpgradeCode to match what I see in the old MSI project (and which is in the windows registry in the uninstall list). I see the UpgradeCode being generated into the WXF file. But when I couldn't get that to work I tried setting it to match the UpgradeCode from the self-installing bootstrapper (which is what the end user runs). That didn't help.
I've read about similar experiences here and here. I've also set the upgrade strategy a few different ways including:
project.MajorUpgrade = MajorUpgrade.Default;
And:
project.MajorUpgrade = new MajorUpgrade
{
Schedule = UpgradeSchedule.afterInstallInitialize,
AllowDowngrades = true,
IgnoreRemoveFailure = true,
AllowSameVersionUpgrades = false
};
And:
project.MajorUpgradeStrategy = new MajorUpgradeStrategy
{
RemoveExistingProductAfter = Step.InstallInitialize,
UpgradeVersions = new VersionRange
{
Maximum = project.Version.ToString(),
IncludeMaximum = false,
MigrateFeatures = false
},
PreventDowngradingVersions = new VersionRange
{
Minimum = project.Version.ToString(),
IncludeMinimum = false
},
NewerProductInstalledErrorMessage = "A newer version of [ProductName] is already installed. Setup will now exit."
};
And various variations on those themes. Nothing I've done has impacted behavior, which is to say after installing, both the old and the new version of the application is listed in the add/remove Windows list. Is there some missing secret sauce to this migration path?
UPDATE:
I've realized my last snippet attempt there is actually working*. It's triggering the removal of everything except the entry in the Windows add/remove programs! Can this be due to a name change for the application in the new installer? Or maybe it's remaining around due to the old bootstrapper somehow, since I'm using the UpgradeCode from the old MSI and not doing anything specific with the bootstrapper?
UPDATE2:
The "old" installer has both an MSI and EXE (bootstrapper) version of the setup. If I just install using the old MSI, then run the new MSI, all works perfectly. So it seems that it is something related to running the bootstrapper EXE that is not getting removed.
Related
I have a bundled application say XYZ-1.0.0.1.exe, with applications A-2.2.0.1.exe and B-1.2.0.1.exe bundled in it. So when we install XYZ, we get A and B as well listed in Add Remove Programs. But when I upgrade XYZ-1.0.0.1 with XYZ-1.0.0.2, which has A-2.2.0.1.exe and B-1.2.0.2.exe, so that A is same and already installed and B needs upgrade. I actually skipped the installation of A by making the install condition false, since the same version is already installed and installed only B while upgrading.
After successfully upgrading I am not able to uninstall the application XYZ, it says some package error, also this happens only if the source file used for upgrading is removed from machine.Actually while uninstalling package has to be referred from program cache, I think since we skipped A package cache has problem.
The error that i get is as follows "Prompt for source of container: WixAttachedContainer, path: C:\Users\ABC\Desktop\XYZ-1.0.0.2.exe Failed to resolve source for file: C:\Users\ABC\Desktop\XYZ-1.0.0.2.exe, error: 0x80070002. Error 0x80070002: Failed while prompting for source (original path 'C:\Users\ABC\Desktop\XYZ-1.0.0.2.exe'). Failed to acquire container: WixAttachedContainer to working path: C:\Users\ABC\AppData\Local\Temp{b4a1c780-306c-40f0-83ad7}, error: 0x80070002. "
This error occurs only when i copy XYZ.exe to any path say desktop and after installation(skip installing A or B since same version of A or B bundled is already installed) and delete the setup file XYZ.exe from saved path ie here Desktop. I am not able to uninstall unless i uninstall A or B which was skipped independently.
Also there is another scenario.
I have a bundled application say XYZ-1.0.0.1.exe, with applications A-2.2.0.1.exe and B-1.2.0.1.exe bundled in it. XYZ-1.0.0.2.exe, which has A-2.2.0.1.exe and B-1.2.0.2.exe. Thes in both versions of XYZ we have the same version of A. When i install XYZ-1.0.0.1.exe i skipped the installation of A-2.2.0.1.exe by setting the install condition to false. So XYZ-1.0.0.1.exe is installed and B-1.2.0.1 is also installed. Further when i upgraded to XYZ-1.0.0.2, I need to install all of the A and B. Installation was successfull and now i have XYZ-1.0.0.2, A-2.2.0.1 and B-1.2.0.2. Now if i delete the installation file of XYZ-1.0.0.2.exe from original path and try to uninstall it breaks.
Initially i thought that the package cache issue arises since A-2.2.0.1.exe was not installed along with XYZ-1.0.0.2.exe since i skipped it as it is already available. But after the second scenario got to know that skipping was not the issue. Since in second scenario A-2.2.0.1.exe was installed along with XYZ-1.0.0.2.exe.
The same issue took huge amount of my time as well. Solved it using a work around. Since the issue is "Prompt for source of container: WixAttachedContainer, path: ", You can copy the exe file XYZ-1.0.0.2 while upgrading to program data or some other path with a default name xyz.exe. At first register for ResolveSource event,then add the following code.Assume the copied exe path is c:/XYZ/xyz.exe
private void OnResolveSource(object sender, ResolveSourceEventArgs e)
{
Application.Engine.SetLocalSource(e.PackageOrContainerId, e.PayloadId, "c:/XYZ/xyz.exe");
e.Result = Result.Retry;
}
If anybody know a better answer, please help.
A simple msi created using WiX. Trying to install a product. On some computers it will fail, without an error, and the installer log will contain these rows:
PROPERTY CHANGE: Adding WIX_UPGRADE_DETECTED property. Its value is '{7C9...0A0}'
PROPERTY CHANGE: Adding MIGRATE property. Its value is '{7C9...0A0}'
Product Code from property table after transforms: '{68F...FAE}'
Product not registered: beginning first-time install
Doing action: INSTALL
Doing action: InstallValidate
Feature: ProductFeature; Installed: Absent; Request: Null; Action: Null
MIGRATE = {7C9...0A0};{A9B...BCE}
Installation completed successfully.
Somehow, Windows Installer decides that there is nothing to do (Request: Null), even though it acknowledges that this is the first time install. That computer had previous version of the product installed. How do I force the installer to install?
Here is the relevant WiX code:
<Product Id="*"
Name="..."
Language="1033"
Version="..."
Manufacturer="..."
UpgradeCode="8D8...196">
<Package Id="*"
InstallerVersion="200"
Compressed="yes"
InstallScope="perMachine"
InstallPrivileges="elevated"
Platform="$(var.Platform)" />
<Property Id="REINSTALLMODE" Value="amus" />
<MajorUpgrade AllowDowngrades="yes" IgnoreRemoveFailure="yes" AllowSameVersionUpgrades="no"/>
<Feature Id="ProductFeature" Title="..." Level="1" Absent="disallow" AllowAdvertise="no" InstallDefault="local" TypicalDefault="install">
<Condition Level="1">True</Condition>
Full installer log: https://www.dropbox.com/s/abnryavh203a82w/acme_installer_log.txt?dl=0
You did not set MigrateFeatures in your MajorUpgrade element. The documentation says the default value is Yes.
http://wixtoolset.org/documentation/manual/v3/xsd/wix/majorupgrade.html
The log shows you are doing an upgrade, therefore the only features that are going to be installed is the same set that are already installed.
It's not clear how many features there are in your product, but if you always want all features to be installed during an upgrade set MigrateFeatures to No.
Either way, it would be better to supply the entire log to see what's going on and if there is another explanation.
This got too long for a comment, adding as an answer. Just a couple of things:
You definitely should not set REINSTALLMODE="amus" for any MSI package.
If you include merge modules in this setup you could downgrade shared files - even if you otherwise don't write to shared locations yourself.
The best would be the default "omus", but I guess "emus" is also ok (Reinstall if the file is missing, or is an equal or older version).
It certainly looks like the MigrateFeatureStates action is at least related to the problem seen:
MigrateFeatureStates: based on existing product, setting feature 'ProductFeature' to 'Absent' state.
Your INSTALLLEVEL property looks fine.
You might want to open the compiled MSI and verify that there are no entries in the Condition table (which can change feature selection states). There should be nothing there, but perhaps just verify.
I suppose you could try to set the Absent attribute for the WiX Feature element to "disallow", recompile and see if this changes things. If this is your only feature I would make this change in addition to using Phils suggestion to set MigrateFeatureStates to "No". Why allow your only feature to be removed?
It is a little odd how this problem has occurred. Perhaps you ran modify on your MSI and simply selected the feature to be uninstalled in the old installation on the machine? Sounds unlikely - especially if it is your only feature.
Did you install several earlier versions of your product on the machine in question, or was there only one prior version?
Again, are there entries in the "Condition table" in the compiled MSI? (Check using Orca).
Did you change the feature name in your newest package?
In any event you should be able to "fix" the broken install by 1) simply running your existing setup and adding ADDLOCAL=ALL to your msiexec.exe install command - I think that will override the MigrateFeatureStates action (not a real fix, just a workaround). Or 2) you can disable MigrateFeatureStates and recompile the setup - that should fix things permanently, and 3) if I were you I would set the Absent attribute for the WiX Feature element to "disallow" so that your (only?) feature can't be removed.
Phil, if you see this, do you know what the MIGRATE property seen in the log is about? It looks like some WiX specific stuff - unless it is something from this MSI's upgrade table:
MSI (c) (04:24) [13:01:38:751]: Doing action: FindRelatedProducts
MSI (c) (04:24) [13:01:38:751]: Note: 1: 2205 2: 3: ActionText
Action 13:01:38: FindRelatedProducts. Searching for related applications Found application: [1]
Action start 13:01:38: FindRelatedProducts.
FindRelatedProducts:
MSI (c) (04:24) [13:01:38:751]: PROPERTY CHANGE: Adding WIX_UPGRADE_DETECTED property. Its value is '{7C945F97-A2CC-4EEB-87AC-3D23D6C490A0}'.
MSI (c) (04:24) [13:01:38:751]: PROPERTY CHANGE: Adding MIGRATE property. Its value is '{7C945F97-A2CC-4EEB-87AC-3D23D6C490A0}'.
FindRelatedProducts:
MSI (c) (04:24) [13:01:38:752]: PROPERTY CHANGE: Modifying WIX_UPGRADE_DETECTED property. Its current value is '{7C945F97-A2CC-4EEB-87AC-3D23D6C490A0}'. Its new value: '{7C945F97-A2CC-4EEB-87AC-3D23D6C490A0};{A9B1787A-32E4-4D51-819D-B3F879574BCE}'.
MSI (c) (04:24) [13:01:38:752]: PROPERTY CHANGE: Modifying MIGRATE property. Its current value is '{7C945F97-A2CC-4EEB-87AC-3D23D6C490A0}'. Its new value: '{7C945F97-A2CC-4EEB-87AC-3D23D6C490A0};{A9B1787A-32E4-4D51-819D-B3F879574BCE}'.
Action ended 13:01:38: FindRelatedProducts. Return value 1.
tandrasz: as far as I can see the two GUIDs that are found by FindRelatedProducts ({7C945F97-A2CC-4EEB-87AC-3D23D6C490A0};{A9B1787A-32E4-4D51-819D-B3F879574BCE}), are different from your new setup's product code ({68F5E655-2E2D-492E-B445-BE1650AF5FAE}). This makes it look like there are two "related products" found by FindRelatedProducts on the machine in question. Are two older versions of the same MSI installed, or do you have a "suite" of MSI files that all share the same upgrade code?. If you have two "unrelated" packages installed, perhaps MigrateFeatureStates finds no way to migrate the feature states between those two and the new package you are installing?
I am developing a wix installer. This wix installer installs a 3rdparty msipackage.
I want my wix bootstrapper project to install this msipackage no matter what version that should already exist on the users pc. This means that if the same version(or a newer version) exists it should overwrite that installation.
I install my msipackage like this:
<MsiPackage Id="InstacalFull" Name="Measurement Computing InstaCal" Vital="yes" Compressed="yes" SourceFile="../Suite.SetupBootstrapper/3rdparty/Instacal/InstaCal.msi">
Does anyone have any ideas on how to achieve this?
Use InstallCondition="1"
This will install it every time
http://wixtoolset.org/documentation/manual/v3/xsd/wix/msipackage.html
InstallCondition
String
A condition to evaluate before installing the package. The package will only be installed if the condition evaluates to true. If the condition evaluates to false and the bundle is being installed, repaired, or modified, the package will be uninstalled.
I know this one is old, but since I came across this issue, maybe it would help someone, too.
In my case Repair was enough, so although technically it wasn't reinstall, practically Repair = Reinstall.
I needed to reinstall URLrewrite, because it could get broken when IIS Windows feature was disabled.
What you need it to add custom handler for PlanPackageBegin in you custom BootstrapperApplication class, for example:
CustomBootstrapperApplication.Model.Bootstrapper.PlanPackageBegin += this.PlanPackageBegin;
...........
private void PlanPackageBegin(object sender, PlanPackageBeginEventArgs e)
{
if (e.PackageId.ToLower().Contains("urlrewrite"))
{
if (CustomBootstrapperApplication.Model.Command.Action != LaunchAction.Uninstall && e.State == RequestState.Present)
{
CustomBootstrapperApplication.Model.Engine.Log(LogLevel.Verbose, string.Format("{0} is installed, forcing Repair", e.PackageId));
e.State = RequestState.Repair;
}
}
_packageList.Add(e.PackageId, e.State);
}
And in the the Bundle:
<!-- Note: this Id is used in PlanPackageBegin -->
<MsiPackage Id='urlrewrite2X64' Vital='no'
Permanent='yes'
SourceFile="rewrite_amd64.msi"
DownloadUrl="http://example.com/rewrite_amd64.msi"
DisplayInternalUI="no"
Visible="yes"
InstallCondition="VersionNT64"/>
You can force uninstallation of previous MSI during upgrade by something like this inside PlanPackageBegin:
if (LaunchAction.Uninstall == CustomBootstrapperApplication.Model.Command.Action && (CustomBootstrapperApplication.Model.Command.Relation == RelationType.Upgrade))
{
e.State = RequestState.None;
}
I'm creating a custom wizard-style bootstrapper based on Wix/Burn (3.6 release version). I've based in on the Wix 3.6 bootstrapper code.
The problem is that I cannot get the bootstrapper to detect the install state of my setup.msi that is part of the bundle.
As I understand it, all that's required is to call Engine.Detect(), where Engine is an instance of the Wix Engine from the Bootstrapper Application. At that point I should be able to look in Bootstrapper.Command.Action to see what the required launch action is.
My bundle contains two items: .NET 4 (web install) and my setup.msi.
I suspect that I'm missing a step to determine whether I should put my wizard into maintenance mode vs. install mode.
First, to determine if the package is being detected or not you can check the log files in the temp directory of the current user. It will tell you whether or not the package has been detected.
Now to determine whether or not to go into maintenance mode vs. install mode, you can check the package state by subscribing to the DetectPackageComplete event. In the example below, my UI uses two properties, InstallEnabled and UninstallEnabled to determine what "mode" to present to the user.
private void OnDetectPackageComplete(object sender, DetectPackageCompleteEventArgs e)
{
if (e.PackageId == "DummyInstallationPackageId")
{
if (e.State == PackageState.Absent)
InstallEnabled = true;
else if (e.State == PackageState.Present)
UninstallEnabled = true;
}
}
The code sample above is from my blog post on the minimum pieces needed to create a Custom WiX Managed Bootstrapper Application.
An easy way to determine if your Bundle is already installed is to use the WixBundleInstalled variable. That will be set to non-zero after your Bundle is successfully installed.
Additionally, in WiX v3.7+ the OnDetectBegin callback now tells you if the bundle is installed so you don't have to query the variable normally.
These changes were made to make it easier to detect maintenance mode to avoid the completely reasonable solution that #BryanJ suggested.
I have recently added a WCF service reference to my program. When I perform a clean install of this program, everything seems to work as expected. But, when I install the program on a client which already has a previous version (without the new service reference) installed, I get a exception telling me the default endpoint for this particular service could not be found.
It seems that the appname.exe.config is not being updated with the new endpoint settings. Is there any reason for this and how can I force the installer to overwrite the config file? I'm using the default Visual Studio 2008 installer project with RemovePreviousVersions set to True.
Update:
My program encrypts the settings section after the first run with the following code
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSection section = config.GetSection(sectionKey);
if (section != null)
{
if (!section.SectionInformation.IsProtected)
{
if (!section.ElementInformation.IsLocked)
{
section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
section.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);
}
}
}
When I do not run the program before installing the new version the app.config gets updated.
You are right that it is the config file that is not updated.
There are several possibilities:
The installer has the old version of the config file
The installer does not have a config file and the program is using the old one on the machine
Try uninstalling the project first, then install and check that the config file has been copied in.