BrowseDlg fails to load the image - wix

I have following code snippet to open a Browse Dialog
<Control Id="ChangeFolder" Type="PushButton" X="500" Y="142" Width="56" Height="20" Text="Browse" />
And other publish code to make sure that it calls for default BrowseDlg
<Publish Dialog="InstallLocationDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
<Publish Dialog="InstallLocationDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
However, when I build and click the Browse button, following screen pops up with icons failing to load.
What would you think is the cause of this?
I have used WixUI_InstallDir and saw the icons.
It is just when I want to call BrowseDlg from my UI that is having issue.
Any suggestion would be appreciated.
Thank you.

I was missing <UIRef Id="WixUI_Common"/> by adding it, everything is resolved.

Related

WiX installer browse dialog doesn't update text field

I have the following two controls in my WiX installer that render and work correctly most of the time:
<Control Id="LogPathEdit" Type="Edit" X="134" Y="71" Width="130" Height="15" Property="LOGPATH" Text="[LOGPATH]">
<Condition Action="hide"><![CDATA[&Server<>3]]></Condition>
<Condition Action="show"><![CDATA[&Server=3]]></Condition>
</Control>
<Control Id="btnDirBrowse" Type="PushButton" Width="56" Height="17" X="268" Y="70" Text="Browse..." >
<Condition Action="hide"><![CDATA[&Server<>3]]></Condition>
<Condition Action="show"><![CDATA[&Server=3]]></Condition>
<Publish Property="_BrowseProperty" Value="LOGPATH" Order="1">1</Publish>
<Publish Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
</Control>
However if I edit the LogPathEdit text box before I browse for a directory, the text box doesn't get updated with the value selected from the browse directory dialog. If I just click on the Browse... button and select a directory, the text field gets updated and works correctly.
I've looked at these two links, but they don't solve my issue:
Use WiX browser dialog to set edit box value
Using a WiX property from a browse dialog
Changing the Type from Edit to LogPathEdit solved the issue. Here's the new line:
<Control Id="LogPathEdit" Type="PathEdit" X="134" Y="71" Width="130" Height="15" Property="LOGPATH" Text="[LOGPATH]">

Uninstalling Bundle causes msi to install

I have two Wix projects - one that creates the MSI and the other that bootstraps it into an exe.
Using the exe, I can install the application with no issues, but when I try to uninstall the application, I get my installer's setup menu again and it attempts to install itself again.
If I cancel the re-install, and attempt to uninstall again, it works as expected.
If I perform the same workflow with the msi, it works as expected.
Here's what my bootstrapper looks like:
<Bundle Name="name" Version="2.0.0.0" Manufacturer="company" UpgradeCode="guid" IconSourceFile="icon.ico" DisableModify="yes">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
<bal:WixStandardBootstrapperApplication LicenseFile="license.rtf" SuppressOptionsUI="yes" SuppressRepair="yes" />
</BootstrapperApplicationRef>
<Chain>
<MsiPackage SourceFile="application.msi" DisplayInternalUI="yes" EnableFeatureSelection="yes"/>
</Chain>
</Bundle>
Any ideas?
Update
As per suggestions, I've modified my bundle to the following (set EnableFeatureSelection to no), but it's still showing the same behavior.
<Bundle Name="name" Version="2.0.0.0" Manufacturer="company" UpgradeCode="guid" IconSourceFile="icon.ico" DisableModify="yes">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
<bal:WixStandardBootstrapperApplication LicenseFile="license.rtf" SuppressOptionsUI="yes" SuppressRepair="yes" />
</BootstrapperApplicationRef>
<Chain>
<MsiPackage SourceFile="application.msi" DisplayInternalUI="yes" EnableFeatureSelection="no"/>
</Chain>
</Bundle>
Update #2
I noticed that when I uninstall for the first time and it launches the install setup, if I cancel the setup, it fails, but it has already removed all the files and registry keys. Running the uninstall the second time removes the entry from the Add/Remove programs (successfully).
Update #3
Here's the UI sequence for the msi
<UI>
<DialogRef Id="WelcomeDlg"/>
<DialogRef Id="LicenseAgreementDlg"/>
<DialogRef Id="VerifyReadyDlg"/>
<DialogRef Id="ErrorDlg" />
<DialogRef Id="FatalError" />
<DialogRef Id="FilesInUse" />
<DialogRef Id="UserExit" />
<DialogRef Id="SelectDbDlg" />
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg"></Publish>
<Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">NOT Installed</Publish>
<Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="SelectDbDlg">NOT Installed</Publish>
<Publish Dialog="SelectDbDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg">NOT Installed</Publish>
<Publish Dialog="SelectDbDlg" Control="Next" Event="NewDialog" Value="DbCreateCredDlg">NOT Installed</Publish>
<Publish Dialog="DbCreateCredDlg" Control="Back" Event="NewDialog" Value="SelectDbDlg">NOT Installed</Publish>
<Publish Dialog="DbCreateCredDlg" Control="Next" Event="NewDialog" Value="SetupTypeDlg">NOT Installed</Publish>
<Publish Dialog="SetupTypeDlg" Control="Back" Event="NewDialog" Value="DbCreateCredDlg">NOT Installed</Publish>
<Publish Dialog="SetupTypeDlg" Control="Next" Event="NewDialog" Value="FeaturesDlg">NOT Installed</Publish>
<Publish Dialog="SetupTypeDlg" Control="CustomButton" Event="NewDialog" Value="FeaturesDlg">NOT Installed</Publish>
<Publish Dialog="SetupTypeDlg" Control="TypicalButton" Event="NewDialog" Value="VerifyReadyDlg">NOT Installed</Publish>
<Publish Dialog="SetupTypeDlg" Control="CompleteButton" Event="NewDialog" Value="VerifyReadyDlg">NOT Installed</Publish>
<Publish Dialog="FeaturesDlg" Control="Back" Event="NewDialog" Value="SetupTypeDlg">NOT Installed</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="SetupTypeDlg">NOT Installed</Publish>
<Publish Dialog="ExitDialog" Control="Back" Event="EndDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
</UI>
This sounds like there is an issue with the MSI. Since you have DisplayInternalUI="yes", the UI belonging to the MSI is what you see when the application is being added or removed. My guess is that there is some issue with the order in which the MSI install dialogs are being displayed, or with the conditions on which the MaintenanceTypeDlg dialog is displayed. Without seeing the options set on the MSI, or the publish order for the UI dialogs and the conditions under which they are displayed it is hard to say where the problem lies specifically. An example of what your UI fragment for the MSI looks like would help further diagnose if this is the issue.
----Edit----
As I expected the only path for your UI to follow is the install path, and the condition on the WelcomeDlg element forces it down that path. To fix this, remove the current WelcomeDlg and replace with the following two lines:
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">NOT Installed AND NOT PATCH</Publish>
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>
This will use the bootstrapers welcome screen to determine if the user wants to uninstall and, since there is no Installed condition to publish the VerifyReadyDlg, skip right to the unistallation without publishing any of the MSI's UI dialogs. This appears to be what you are looking to do, however, if you did want to set a sequence of dialogs in the MSI to guide the user through the uninstall, you could add those dialogs here.
After a couple more days of poking at it, I found the problem and it was due to the MSI throwing an error upon uninstall (silently). I have some custom actions defined, but I did not have them set to run only upon install.
So I had this before:
<InstallExecuteSequence>
<Custom Action="ServerName.Set" Before="AdjustConfigurationFile"/>
<Custom Action="AdjustConfigurationFile" Before="InstallFinalize"/>
<Custom Action="CreateDatabase" After="InstallFinalize"/>
</InstallExecuteSequence>
Upon uninstall though, the custom action would run to adjust the configuration file (which would fail becaue the file no longer exisited) which would cause the application to rollback, which would cause the installer to run again.
Changing the Install sequence to the following fixes this issue:
<InstallExecuteSequence>
<Custom Action="ServerName.Set" Before="AdjustConfigurationFile">NOT Installed</Custom>
<Custom Action="AdjustConfigurationFile" Before="InstallFinalize">NOT Installed</Custom>
<Custom Action="CreateDatabase" After="InstallFinalize">NOT Installed</Custom>
</InstallExecuteSequence>
The takeaway here is that if you're uninstalling the bootstrapper and the installer UI shows up again, THE MSI THREW AN ERROR and you should double check that logic.
Add to your MsiPackage element InstallCondition attribute with NOT Installed. If you want run install on upgrade then ypu have to add or UPGRADINGPRODUCTCODE.

Having trouble modifying a Built-in WixUI dialog set

I am trying to remove the license agreement from the built-in WixUI_InstallDir dialog set. I found some helpful instruction here
I've added this to the Product.wxs
<UI Id="InstallDir">
<UIRef Id="WixUI_InstallDir" />
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">NOT Installed</Publish>
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
</UI>
The next button on the welcome dialog happily goes to the install directory dialog, but the back button of InstallDirDlg goes to the license agreement.
Any ideas would be appreciated.
I posted this question in the WiX-user mailing list. The consensus was that trying to change some of the publish commands in a built-in dialog set is not a "recipe for success". Instead I got the source wxs for the WixUI_InstallDir, made a copy of it (WixUI_NOEULAInstallDir), modified it and included in my project. I was trying to avoid having a custom dialog file in all my solutions, but I was able to export a project template that has the custom dialog included, so it's not so bad.

Prompt to uninstall older version of APP in WiX

I developed an installer using Wix 3.6 that installs successfully all elements of an application.
Now, each time I give an msi with a higher version, I want the installer to prompt the user to uninstall it. Since now I've tried this:
<Product
Id="*"
Name="!(loc.ProductName)"
Language="3082"
Codepage="1252"
Version="1.0.1"
Manufacturer="$(var.ProductManufacturer)"
UpgradeCode="$(var.UpgradeCode)">
<Property Id="PREVIOUSVERSIONINSTALLED" Secure="yes" />
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Minimum="1.0.0.0" Maximum="99.9.9.9" IncludeMiminum="yes" IncludeMaximum="no" Property="PREVIOUSVERSIONSINSTALLED" />
</Upgrade>
<InstallExecuteSequence>
<RemoveExistingProducts Before="InstallInitialize" />
</InstallExecuteSequence>
This code successfully uninstalls any previous installed version on my computer. But it doesn't ask the user if he's sure to do so.
What I need is Wix installer to prompt the user saying a message like:
A previous version of your [ProductName] is installed. Do you want to uninstall it? [ Yes | No ] option.
Is there any way to prompt user and check if he really wants to uninstall any previous version?
The Windows Installer Upgrade table has an attribute bit called msidbUpgradeAttributesOnlyDetect that is represented by WiX's UpgradeVersion#OnlyDetect attribute.
When properly authored this causes FindRelatedProducts to set an action property of your choosing with the ProductCode GUID(s) of detected products. It does not pass this off to RemoveExistingProducts for automatic removal though.
While not the typical behavior, there is nothing stopping you from writing some UI that gets triggered when this property has a value. You could ask the user if they want to remove the old version and if yes, set another action property to tell RemoveExistingProducts. (Hint: Author a Upgrade that would never find a product on it's own and hijack it's property to inject the removal. )
If the user says no, you have the choice of aborting the install or continuing the install side by side to a different directory structure. ( Office, Visual Studio et al ).
I found this post useful when solving the same problem. You can use the PREVIOUSVERSIONINSTALLED property you set in the upgrade-tag to open a custom dialog. Do this inside some UI-tags by adding the following code (when using the standard welcome dialog):
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="OldVersionDlg">PREVIOUSVERSIONSINSTALLED</Publish>
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="SetupTypeDlg">NOT Installed AND NOT PREVIOUSVERSIONSINSTALLED</Publish>
I based my own custom dialog on this Wix tutorial, and ended up with the following code:
<Dialog Id="OldVersionDlg" Width="260" Height="85" Title="[ProductName] Setup" NoMinimize="yes">
<Control Id="No" Type="PushButton" X="132" Y="57" Width="56" Height="17"
Default="yes" Cancel="yes" Text="No">
<Publish Event="EndDialog" Value="Exit">1</Publish>
</Control>
<Control Id="Yes" Type="PushButton" X="72" Y="57" Width="56" Height="17" Text="Yes">
<Publish Event="EndDialog" Value="Return">1</Publish>
</Control>
<Control Id="Text" Type="Text" X="48" Y="15" Width="194" Height="30">
<Text>A previous version of [ProductName] is currently installed. By continuing the installation this version will be uninstalled. Do you want to continue?</Text>
</Control>
</Dialog>

Is it possible to localize EULA in WiX using .wxl file?

My installer, created wth WiX is localized via .wxl files. It is possible in WiX to specify multiple cultures and light.exe will be called multiple times, creating an installer for each language (this is available while building installer from Visual Studio).
All works file except for EULA. It is defined in .wxs file via
<WixVariable Id='WixUILicenseRtf' Value='en.rtf' />
And i don't know a good way to change this value from .wxl localization file. Using
<WixVariable Id='WixUILicenseRtf' Value='!(loc.EulaFile)' />
<String Id='EulaFile'>en.rtf</String>
Is not working, sice .wxl files are used at link-time and .wxs is compiled before them, so compiler can't find !(loc.EulaFile). Searching forums i have found two workarounds. First is to create a custom license dialog for each language - it seems to work, but it's a very hard way and bloat source code a lot. Second way is to drop Visual Studio / Votive build and to call light.exe multiple times, specifying different license file each time via -d command-line key.
Is it any way to solve this problem and use localized EULA files so project can be built in VisualStudio + Voltive without a need to copy-paste lots of dialogs? Localizing installers is a very common problem, so maybe some solution exist that i don't know about?
There is another way to do this, and although it is a bit messy it is less messy than the two workarounds the OP has mentioned. And credit where credit is due, this answer is almost 100% based on this post http://weblogs.sqlteam.com/mladenp/archive/2010/04/15/WiX-3-Tutorial-Custom-EULA-License-and-MSI-localization.aspx by Mladen Prajdić.
The following is based on WiX 3.5.
You create a slightly modified copy of the LicenseAgreementDlg dialog and include it in your project.
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) Microsoft Corporation. All rights reserved.
The use and distribution terms for this software are covered by the
Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
which can be found in the file CPL.TXT at the root of this distribution.
By using this software in any fashion, you are agreeing to be bound by
the terms of this license.
You must not remove this notice, or any other, from this software.
-->
<!-- This is a modified version of LicenseAgreementDlg to support selection of localized versions of
the license file. It is very much based on this article:
http://sqlserverpedia.com/blog/sql-server-bloggers/wix-3-tutorial-custom-eula-license-and-msi-localization/ -->
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<UI>
<Dialog Id="LicenseAgreementKludge" Width="370" Height="270" Title="!(loc.LicenseAgreementDlg_Title)">
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.LicenseAgreementDlgBannerBitmap)" />
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Description" Type="Text" X="25" Y="23" Width="340" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.LicenseAgreementDlgDescription)" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.LicenseAgreementDlgTitle)" />
<Control Id="LicenseAcceptedCheckBox" Type="CheckBox" X="20" Y="207" Width="330" Height="18" CheckBoxValue="1" Property="LicenseAcceptedKludge" Text="!(loc.LicenseAgreementDlgLicenseAcceptedCheckBox)" />
<Control Id="Print" Type="PushButton" X="112" Y="243" Width="56" Height="17" Text="!(loc.WixUIPrint)">
<Publish Event="DoAction" Value="WixUIPrintEula">1</Publish>
</Control>
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" />
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)">
<Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg">!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1</Publish>
<Condition Action="disable"><![CDATA[LicenseAcceptedKludge <> "1"]]></Condition>
<Condition Action="enable">LicenseAcceptedKludge = "1"</Condition>
</Control>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
<Control Id="LicenseText" Type="ScrollableText" X="20" Y="60" Width="330" Height="140" Sunken="yes" TabSkip="no">
<Text SourceFile="$(var.ProjectDir)\!(loc.LicenseRtf)" /> <!-- this value has been modified -->
</Control>
</Dialog>
</UI>
</Fragment>
</Wix>
In your main WiX source file you add the following code to "patch" your new dialog into the dialog sequencing instead of the original one:
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementKludge">1</Publish>
<Publish Dialog="LicenseAgreementKludge" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
<Publish Dialog="LicenseAgreementKludge" Control="Next" Event="NewDialog" Value="InstallDirDlg">LicenseAcceptedKludge = "1"</Publish>
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementKludge">1</Publish>
Note that this is based on using the WixUI_InstallDir dialog collection - for other collections, such as WixUI_Mondo, you will probably have to modify the above by looking at the source.
Finally, in each of your localization files you place one line like this:
<String Id="LicenseRtf">en-us\MerliniaSMSGatewayLicense.en-us.rtf</String>
<String Id="LicenseRtf">da-dk\MerliniaSMSGatewayLicense.da-dk.rtf</String>
And, of course, you place the localized license file as indicated. I'm placing the license files (and localization files) in subfolders, but this is not necessary.
Like I said, it's a bit messy, but it does work.
Best solution is the simplest, just use the WixUILicenseRtf variable on the command line when specifying your .wxl file.
light -loc setup_fr-FR.wxl -dWixUILicenseRtf=EULA_fr-FR.rtf ...
Refer User Interface Basics at WiX Wiki for more information.
Localizing the EULA is very simple. Add a ScrollableText Control to one of your dialogs. Reference a localization String in the text element of the ScrollableText Control.
<Control Id="LicenseText" Type="ScrollableText" X="20" Y="60" Width="330" Height="140" Sunken="yes" TabSkip="no">
<Text>!(loc.License)</Text>
</Control>
Next create a localization file, say for american english. Name the file en-US.wxl. Create a localization String element in the localization file which uses the identifier referenced in the Text element of the ScrollableText Control, in this case it's called License. Add the raw rtf string of your EULA as a CDATA element of the localization string.
To get the raw data, create an rtf file with wordpad, for example. Open that rtf file with notepad and copy its content. Paste that content into the CDATA element of the localization String element. Be sure to omit all whitespace between the String and CDATA Tags.
An example localized String element follows:
<String Id="License"><![CDATA[{\rtf1\ansi\ansicpg1252\deff0\deflang1031{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
{\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\sa200\sl276\slmult1\lang7\f0\fs22 American EULA.}]]></String>
So the key to including multiple EULA's is to use the raw rtf data in the respective localization files.
Go to Solution's Configuration Manager, on the installer project line create a new configuration for each localization you want to use, like the following for example:
Now, on the installer project properties page / Build, for each created configuration, set a single culture on "Cultures to build" and set a different value on "Define variables" box each culture:
For instance, for es-ES:
WixUILicenseRtf=.\Assets\license-es-ES.rtf
For en-US:
WixUILicenseRtf=.\Assets\license-en-US.rtf
... etc
To build your installers:
For each culture:
Go to the configuration manager,
Select the configuration culture for the installer, accept
Build
Pros:
No need to deal with custom actions, custom dialogs or console commands
Only need to config it once. Making it run is a mechanic task
Cons:
Needs some extra clicks for each build
Messy with more than three cultures