Wix MSI installer fail when changing build image in Azure Pipelines - wix

As noted here a bunch of legacy images in Azure Pipelines are being removed in a few days. We have had some code using WIX building in Azure Pipelines for a few years now - using one of the images being deprecated (vs2015-win2012r2).
If I change my build image to e.g. vs2017-win2016, I get this error from my Azure Pipeline:
##[error]C:\Program Files (x86)\MSBuild\Microsoft\WiX\v3.x\wix2010.targets(2439,7): Error
MSB4064: The "AllowDuplicateDirectoryIds" parameter is not supported by the "Light" task.
Verify the parameter exists on the task, and it is a settable public instance property.
UPDATE:
I can now also reproduce this locally. And I have found out that one of the changes from WIX 3.10x to 3.11x is this particular parameter:
AllowDuplicateDirectoryIds
I can also see that the Azure Pipeline image vs2017-win2016 has WIX3.11 whereas the Vs2015-Server2012R2 has WIX3.10 installed.
So everything fits ... my solution fails to build because it was targeted WIX 3.10 but the new image has WIX 3.11 installed.
So something inside my C# installer project still references Wix 3.10 and fails because the new 3.11 has some functionality that Wix 3.10 did not have.
What could that be?

As what you found, the wix version that vs2017-win2016 image used is 3.11. And also, unfortunately, we does not support to install customized wix version to override the one that located in Hosted agent until now.
In your scenario, you can consider to use one work around: set up private agent to build your project. Just ensure it is wix 3.10 exists in your local machine that private agent installed.
When build with this private agent, the system will detect corresponding tools from local system. So, it would be succeed if you ensure there has wix 3.10 located in the machine that private agent located.

Related

how to download custom software and install using WIX

I am writing managed bootstrapper application and would like to make it work like Web-based installer (force it to download msi from webserver).
Where will product be downloaded by default? Why SourceFile is mandatory for download of package?
please share sample code.
Separating the concerns:
Managed bootstrapper application
Great. The standard application is very basic. The managed bootstrapper application for WiX itself shows how creative you can get.
Work like Web-based installer
From the following questions, it seems you know about the DownloadUrl attribute.
Where will product be downloaded by default?
It would be a special case to have to know this. The bootstrapper engine (burn) is a package manager and takes care of performing operations with the downloaded package.
Why SourceFile is mandatory for download of package?
SourceFile indicates the location on your build machine. WiX creates a checksum from it so burn can tell if the download is corrupted or different than what was planned.

How to define WIX agent requirement in TeamCity?

I have add a WIX installer project to solution in Visual Studio 2013. The project is built with every commit on TeamCity. There are several build agents connected to TeamCity cloud, but only some have WIX installed.
Usually I would add the build agent requirement, so only the computer with WIX installed is selected for automated build.
What requirement should I select? Is there some environment variable I could use after WIX is installed?
I know I can set the environment variable manually on every computer I install WIX, but this is not nice solution for me.
There's a system environment variable called 'WIX', which holds the path WiX Toolset is installed to. It is created during WiX Toolset installation.
However, there might be a better way that avoids setting up any build agent requirements. Take a look at this article that explains how to integrate WiX into daily builds. Basically, it suggests committing the required binaries along with the source code of your app.
Both approaches have pros and cons, it's your choice.
The agent need to be restarted after installing WIX. Then there will be
env.WIX
requirment in the Teamcity.

Wix binaries in TFS preview

I want to add WIX binaries in TFS preview website how to do that
I have vs 2012 along with build on tfs 2012 in windows server 2012
Here are the specific steps to achieve what you are looking for.
Integrate the WiX toolset into your source control - that link gives you the steps to use the binaries.zip file to get the tools and check them into your build system.
Suppress ICE validation in your .wixproj - the TFS build servers do not allow validation to work so set the SuppressValidation Property in MSBuild to true.
<PropertyGroup>
<SuppressValidation>true</SuppressValidation>
</PropertyGroup>
Manually run validation - validation is like static analysis, it will find problems before you ship to your customers. So, after each build, use smoke.exe to run validation on your MSI on a local server:
smoke.exe path\to\your.msi
It seems WiX is now preinstalled on the hosted TFS build servers. However, ICE validation still fails due to environmental constraints.
If you use Votive to create your .SLN/.WIXPROJ/.WXS and go into project properties and disable validation, it should build without doing anything else.
That said, disabling validation is a non-starter for me. Therefore, I'd suggest setting up your own build server and installing WiX 3.7 on it.

Automatic updating and upgrade management for Windows Installer XML (WiX)

I have been using InstallShield LE in Visual Studio 2010, but it is heavily limited and sometimes buggy. I looked at paid InstallShield versions, but these also have too many limitations for that price tag.
So I decided to switch to WiX. I have had some experience with it some years ago. It was pretty easy to build a simple installer using SharpDevelop with WiX tools.
Now I am trying to collect solutions and tools for WiX. Basically, I need to get the following functionality (requested by my client):
when I launch the installer, it should check a text file on the server and see if a newer version is available. If it's the case, then the installer should be able to download the updated installer package and launch it (are there any downloader utilities in WiX?)
solving dependencies. Major dependency of my app is .NET 4 (which itself depends on Windows Installer 3). The installer should offer the user to download and install them automatically
logging the installation process, also collecting the log file of the dependencies' installation process. I don't want the user to hunt various .log files in case .NET4 or WindowsInstaller3 installation fails. All the information should be collected in one place and if something fails, I should show the user a custom popup dialog with an option to save the complete install log file and send it to me
installer should be able to detect if there is a newer version of my app already installed, and show a meaningful customized error message before it exits
installer should be able to detect if there is an older version of my app already installed. and offer the user to exit installation or uninstall the previous version and install the new version. BTW, there are no minor component upgrades planned, I prefer to reinstall everything fresh (I guess, this is a major upgrade in the terms of WindowsInstaller). Installshield LE failed on me for this, it just showed an error box with the message about another product, but did not offer to uninstall it
in case of an upgrade, installer should be able to detect if some of application components are in use (running application processes) and show a custom error message and not just some cryptic "Installation failed"
I have read that it may be a bit painful to manage upgrades even if I keep my UpgradeCode intact, because this code is stored in the Windows Registry in a compressed way and also if the user renames the downloaded file, it might get detected as a completely new product by WindowsInstaller ... or maybe this is only the case with WindowsInstaller .msi files and WiX has some trick to avoid this issue?
About update downloading - I need this functionality also in my application itself. I am not sure how to implement it efficiently, so I can reuse the same update downloader code/utility in both WiX installer and in my app.
Is it possible to satisfy all these requirements using currently existing WiX tools, or maybe I'll need to code some components from scratch?
WiX is definitely the way to go in my opinion.
when I launch the installer, it should check a text file on the server and see if a newer version is available. If it's the case,
then the installer should be able to download the updated installer
package and launch it (are there any downloader utilities in WiX?)
In my opinion, this type of functionality is best handled by the application. However you can implement such functionality in a custom bootstrapper. The latest development of WiX includes a bootstrapper engine Burn that allows you to write your own custom bootstrapper on top of it.
solving dependencies. Major dependency of my app is .NET 4 (which itself depends on Windows Installer 3). The installer should offer
the user to download and install them automatically
You can use the standard WiX bootstrapper to install .NET as a prereq. Or if you create your own custom managed bootstrapper application, you can install .NET a prereq to your bootstrapper as in this example
logging the installation process, also collecting the log file of the dependencies' installation process. I don't want the user to
hunt various .log files in case .NET4 or WindowsInstaller3
installation fails. All the information should be collected in one
place and if something fails, I should show the user a custom popup
dialog with an option to save the complete install log file and send
it to me
Using the two bootstrapping methods above, when you launch your msi you can specify parameters for logging. In my own custom managed bootstrapper I created a button to open the log files created during installation.
installer should be able to detect if there is a newer version of my app already installed, and show a meaningful customized error
message before it exits
You can do this using launch conditions
installer should be able to detect if there is an older version of my app already installed. and offer the user to exit installation or
uninstall the previous version and install the new version. BTW,
there are no minor component upgrades planned, I prefer to reinstall
everything fresh (I guess, this is a major upgrade in the terms of
WindowsInstaller). Installshield LE failed on me for this, it just
showed an error box with the message about another product, but did
not offer to uninstall it
In my experience this major upgrades are the least complicated
approach.
in case of an upgrade, installer should be able to detect if some of
application components are in use (running application processes) and
show a custom error message and not just some cryptic "Installation
failed"
I think WiX/Windows Installer are generally good at handling these
scenarios and automatically notifying the user that
files/applications need shutdown without you having to author
anything extra in your installer.
All that said, you may want to look into creating your own custom managed bootstrapper using WiX and Burn. That is not trivial however. The best place to go is to download the source code to the WiX Weekly Releases and checkout the project src\Setup\WixBA. It is the custom BA that they wrote to install WiX. There isn't much documentation out there yet because WiX 3.6 is not released (although it is pretty stable). However you don't have to create your own BA to make a solid WiX installer that can handle upgrades and logging.

WiX: Forcefully launch uninstall previous using CustomAction

I'm writing a new major upgrade of our product.
In my installer I start by finding configuration settings of the previous version, then I'd like to uninstall the previous version.
I have found several guides telling me how one should make a MSI suitable for such upgrades.
However, the previous was not an MSI.
It was not according to best practices.
It does, however, in registry HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{GUID} specify an UninstallString.
Using a RegistrySearch I can easy find the command below, which I store in UNINSTALL_CMD.
RunDll32 C:\PROGRA~1\COMMON~1\INSTAL~1\PROFES~1\RunTime\10\01\Intel32\Ctor.dll,LaunchSetup
"C:\Program Files\InstallShield Installation Information\{GUID}\setup.exe"
-l0x9 -removeonly 4:
I cannot get the hang of the CustomAction needed to perform the actual uninstall.
<CustomAction Id="ca.UninstPrev" Property="UNINSTALL_CMD" ExeCommand="" />
The MSI logs says:
Info 1721. There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: ca.UninstallPrevious, location: RunDll32 C:\PROGRA~1\COMMON~1\INSTAL~1\PROFES~1\RunTime\10\01\Intel32\Ctor.dll,LaunchSetup "C:\Program Files\InstallShield Installation Information{GUID}\setup.exe" -l0x9 -removeonly, command:
Anyone seeing what I am doing wrong here?
Regards
Leif
I did application repackaging for a couple years at Continental Airlines where I did SMS pushes to an 18,000 seat forest. I frequently had a legacy application in the wild that was not installed using MSI that I needed to get redeployed using MSI and once that was done I supported major upgrades going forward.
These previously deployed apps typically had very broken and misbehaved uninstallers. Instead of calling these, I would use SMS to query the forest to get all the deployed versions. I would then deploy those old packages to a integration lab and work out what it was each installer did to the machine and write my own aggregated "forced cleanup" custom action that was capable of wiping the various versions of the application off the machine.
I executed this custom action prior CostInitialize so that when the new MSI did it's costing it wouldn't be influenced by the crap that was no longer on the machine. This worked for me because I pushed packages as System and I didn't have to worry about elevation issues. If you want to be fully UAC compliant you would want to run this custom code from a prereq package and either have your users run it manually or wire it into a bootstrapper to run prior to your MSI.
After a good nights sleep I found my error.
If you really read http://wix.sourceforge.net/manual-wix3/wix_xsd_customaction.htm the answer was there.
I was trying to make a type 50 custom action, launch an executable already installed on system.
Property specifies the full path to an executable to launch
ExeCommand specifies the command line arguments for this executable above.
And my fault was that I did place the full exe+command line in the Property field.
/L