Creating localized WIX 3.6 bootstrappers. - visual-studio-2010

I created a WIX project in Visual Studio 2010 over a year ago. It creates an MSI file and a bootstrapper setup.exe. Actually, it creates that pair of files for two languages - English and French. I am just now integrating this project into our TFS CI builds. I'm having trouble getting the CI build to generate the bootstrapper setup.exe files.
We've recently upgraded Wix on all our build servers to Wix 3.6 RC. So, I thought I'd give Burn a try instead of using the old style of bootstrapper. I added a new Bootstrapper project to my solution. The bootstrapper project includes a simple bundle.wxs that just loads the MSI generated by my old MSI project. However, when I try to build I get the following error:
error LGHT0103: The system cannot find the file
'C:\Tf\Advantage\Dev\Solution\Configuration\LaunchPad.Wix\bin\Release\fr-fr\LaunchPad.msi;C:\Tf\Advantage\Dev\Solution\Configuration\LaunchPad.Wix\bin\Release\en-us\LaunchPad.msi'.
My package reference in the bundle looks like this:
<MsiPackage Id="MyApplication" SourceFile="$(var.LaunchPad.Wix.TargetPath)" />
LaunchPad.Wix is the name of the Wix MSI project. If I change the LaunchPad.Wix project to build only one language then it works fine. It looks to me like the bootstrapper project type just doesn't support building setup files for multiple languages. Is this true? Any suggestions for a workaround?
Edit
Upon further investigation, I wonder if bootstrapper projects even support localization. I tried setting my Wix MSI project to create only fr-fr. The setup.exe that my bootstrapper project created with English. When I edit the project properties for the bootstrapper project the "Cultures to build" field is locked down and blank. How would I build a non-english bootstrapper? Is this possible yet?

There are several things going on here:
If you use multiple Cultures, you can't use TargetPath in something outside MSBuild that expects a single filename. As you found, TargetPath is a list of the localized files that were built. However, you can use TargetPath if you qualify the .msi package's output language: <MsiPackage SourceFile="$(var.TestMsi.en-US.TargetPath)" Id="MsiEnUs" />
If you want to create one bootstrapper that can install either/both en-US and fr-FR, you'll need to list each .msi package separately in its own MsiPackage element.
If you want to create two bootstrappers, one en-US and one fr-FR, you'll need to invoke the bootstrapper .wixproj twice, once for each language. Bootstrappers don't support the Cultures "trick" -- it's problematic to produce two outputs from a single invocation of MSBuild (witness the TargetPath problem).
If you're using WixStandardBootstrapperApplication, it automatically tries to localize the UI based on the user UI language, falling back to the system UI language, and finally falling back to English. It looks for localized strings in directories named after the LCID, so you'd have payloads like this:
<Payload Name="1033\thm.wxl" SourceFile="..." />
<Payload Name="1036\thm.wxl" SourceFile="..." />
Unfortunately, WixStandardBootstrapperApplication strings are currently available only for en-US. That's why an fr-FR bootstrapper shows UI in English. You'd need to localize the WiX source file HyperlinkTheme.wxl or RtfTheme.wxl (depending on which theme you use). Both of these files are in src\ext\BalExtension\wixstdba\Resources.

good. it works as Bob Arnson said.
but you must pay attention to the name and the SourceFile of payload.
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
<Payload Name="2052\thm.wxl" SourceFile="2052\thm.wxl" />
</BootstrapperApplicationRef>
if you change the name to another one. the bootstrapper will not be localized.

Related

How to get the Configuration and Platform of a Referenced Project in MSBuild?

I'm creating a custom UI installer with Wix's Burn bootstrapper for a x86/x64 application. In the solution are 4 projects:
App to be installed
Wix Installer
Wix Bootstrapper
Custom UI
For both Wix projects, I edit the .Wixproj files (unload project -> edit project file) and use the BeforeBuild and AfterBuild to publish and rename their respective WPF projects to ensure everything is current and orderly. For instance, the final Setup.exe can be named something descriptive like Setup-[AppToInstall's version]-Debug-x64.exe.
The Problem
AFAIK, the bootstrapper projects and any custom UI must be 32-bit, while the App project and Wix Installer don't have that limitation. So in the bootstrapper project file, I can't ever use the $(Platform) variable because it will always be the bootstrapper's platform, which will always be x86. But what if I want to build the x64 version?
So I need a way to get the 'AppToInstall's' platform in the .Wixproj; something like this:
<GetAssemblyIdentity AssemblyFiles="..\appToInstall\bin\$(appToInstall.Configuration)\netcoreapp3.1\win-$(AppToInstall.Platform)\publish\AppToInstall.dll">
<Output TaskParameter="Assemblies" ItemName="AppAssemblyVersion" />
</GetAssemblyIdentity>
Wix has handy variables for this (i.e $(var.AppToInstall.Platform)) that can be used inside the Bundle.wxs if the AppToInstall.cproj is referenced, but these can't be used directly in the .Wixproj file. How can this be done?

Building MSI from TFS Build

I am trying to build MSIs in a TFS Build by shelling out to DEVENV.exe (since MSBUILD does not support VSPROJs). In any case, my first installer project builds fine, the second one fails. If I reverse the order, same thing happends (i.e. the error does not follow the project). Looking at the output, I get the following errors:
Deserializing the project state for project '[MyProject].dbproj'
[MyProject].dbproj : error : Error HRESULT E_FAIL has been returned from a call to a COM component.
Also, I get:
Package 'Microsoft.VisualStudio.TestTools.TestCaseManagement.QualityToolsPackage, Microsoft.VisualStudio.QualityTools.TestCaseManagement, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' failed to load
It looks as though the first build tries to serialize the DB project (and it says it succeeds, but there is no DBML file anywhere). Then the second build tries to deserialize the DB project and fails.
I've tried resetting env settings (using the /resetusersettings flag) as well as using the /resetskippkgs flag. Nothing works.
Any ideas?
When you shell out to DevEnv, are you building that specific project (.vdproj file), or are you building the solution? It sounds like VS is trying to open the solution on the build machine and the database and test project systems aren't present.
Have you considered porting your setup project to WiX?
Start simple. Unless you're well versed in the problem you're trying to solve it's usually best to try it "by hand" before getting it running as part of a TFS build. RDP into the build server and try running the necessary commands at the command line and see what happens. You can even go simpler than that and RDP into the build machine and load Visual Studio and build it.
Bottom line is that if you can't get it to build within Visual Studio or at the command line by calling devenv.exe it won't work as part of the team build.
I am using the below Exec task to do precisely what you are doing as part of a TFS build. So I know this works. Your platform and configuration may vary depending on what you're building. The nice thing about this is that you'll have a log file at C:\Temp\MSIBuildOutputLog.txt that you can analyze for additional errors and information.
<Exec Command=""C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" "$(PathToSolution)\solution.sln" /Build "Release|Mixed Platforms" /out "C:\Temp\MSIBuildOutputLog.txt"" />
One important thing to note... There is a bug in VS2010 which causes MSI generation to fail when you try to run it at the command line using devenv.exe. This took me days to find and figure out, but you need this hotfix. Worked like a charm...
http://archive.msdn.microsoft.com/KB2286556
Actually it's the deployment projects that don't support msbuild. FWIW, this is all deprecated in the next release of Visual Studio so you might want to start looking at InstallShield Limited Edition and/or Windows Installer XML now before spending too much time on dead end, broken technology. Both of these alternatives have proper MSBuild support aswell as many other improvements.
It would be perhaps better and quicker to adopt WIX (Windows Installer XML) which is the technology MS now recommends to use within VS/MSBuild/TFSBuild environment to crate MSIs.
It is relatively easy to setup and integrate within your VS Solutions. It uses XML based files to describe your MSIs and uses these files to create your MSIs when you compile.
I would start by downloading Wix from http://wix.codeplex.com/
Once installed you would be able to use the VS2010 integration of Wix based projects to create MSIs. To get started quickly simply add a new Wix project to your solution and reference the projects whose output you wish to combine into an MSI. Next you can run a tool called "Heat" which is included with Wix toolkit to generate the XML files by scanning your projects.
Once you have these XML files, add them to your Wix project and compile.

Getting Visual Studio to build pseudo-language (qps-ploc) satellite assemblies

I've generated pseudo-localized versions of an app's resource files (for example Order Summary and Payment is localized as [[[[[Òŕd̂ër̊ S̀úm̂m̈år̀ý ân̈d̊ P̀áŷm̈e̊ǹt́]]]]]) so that we can test for localizability bugs ahead of getting actual translations.
I have named them using the qps-ploc resource identifier to match the existing pseudo-locale identifier, e.g. my pseudo-localized version of Details.resx is named Details.qps-ploc.resx.
However when I add these resx files to the project, Visual Studio ignores them. If I rename them using a "real" language code (such as Details.fr-FR.resx) then Visual Studio does create a subfolder named with this language code and builds the satellite assembly.
So it looks to me like Visual Studio rejects qps-ploc (without even a build warning). Am I missing something or can anyone suggest a way to get these qps-ploc resources built as part of my Visual Studio project?
The qps- locales work fine in my ASP.NET web application with .resx files (not compiled resource dll), however, I did find this MS article on enabling pseudo locales in the registry. Perhaps it will help.
Using Pseudo-Locales for Localization Testing
Additionally, you may wish to create custom locales, as given in this MS article:
How to: Create Custom Cultures
Best regards.

How do I change the language of a Wix 3.5 MSI?

I have created an installer with Windows Installer XML 3.5 from within the Visual Studio 2010. The installer itself works pretty well but now I would like to change it's default language from english (1033) to german (1031). Therefore I changed the language attribute within the product tag to "1031" which should do the magic as far as I know but nothing happens. The language is still english.
<Product Id="MyProductId" Name="NameOfMyApp" Language="1031" Version="MyVersionNumber" Manufacturer="MyCompany" UpgradeCode="MyUpgradeCode">
What am I missing here?
You can also do it in Visual Studio: Project - Properties - Build - Cultures to build.
You need to specify the language (culture) on the command line when building as described here (or in the project properties when you are using Votive):
WiX Tutorial - Do you speak English?
candle.exe SampleWixUI.wxs
light.exe -ext WixUIExtension -cultures:de-de SampleWixUI.wixobj

How to add "visual studio"-reference to WIX in Visual Studio 2010?

I've got a solution with many projects and WIX setup project. I'm using WIX 3.5.
One project (that is referenced from WIX setup project) contains a reference (an ordinary reference in VS) to:
C:\Program Files\WPF Toolkit\v3.5.50211.1\WPFToolkit.dll
(simply: setup project --- reference --> another project in solution --- reference --> WPFToolkit.dll; note that the "references" are not the same - the first one is some kind of WIX specific reference and the other is ordinary reference in Visual Studio)
I thought that maybe the line (automatically generated) in setup project:
<ComponentGroupRef Id="Product.Generated" />
may solve it for me (i.e. includes also WPFToolkit.dll in installer) but it doesn't.
Obviously, I can add the file manually in my wxs file but it will be harder for maintenance.
Is there a better solution?
Thanks!
If you want your install project to be more extensible when adding new WiX Files to a Component, I would suggest to create an external tool (could be a c# console app) to handle the WiX Files generation and add them to your install project. This tool can have a config file where you can setup which WiX Files correspond to each Component.
This tool can be added to an Automated Build process.
What you are seeing is an initial attempt to do exactly what you want via the WiX toolset. On the Property Grid for References to other projects in your .wixproj, you should have the ability to control "Harvesting" and what project output groups are harvested. Unfortunately, there are still some bugs in the feature so it doesn't always work.
If you want to get your hands dirty you can look at the Heat project harvester and how it gets wired into the .wixproj.

Resources