WiX Bootstrapper ShowFilesInUse shows app name as "A" - wix

I have a bootstrapper WiX project which can run a x86 or x64 MSI, depending on CPU. It works well. I set the ShowFilesInUse to "yes" so WiX can optionally kill running app or require restart.
However, if the app is running, the dialog shows the app name always as just "A" instead of the actual app name.
Just "A" nothing else. In the Task Manager my running app clearly shows it has a name of "My App" or MyApp.exe.
I'm not sure what I'm missing here.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<?include $(sys.CURRENTDIR)\..\MyApp\WIX_Version.wxi?>
<?include $(sys.CURRENTDIR)\..\WiXSetup x64\Variables.wxi?>
<Bundle Name="My App" Version="$(var.ProductVersion)" Manufacturer="My Company LLC" UpgradeCode="$(var.UpgradeCode)" AboutUrl="http://www.mywebsite.com/tools/MyApp" IconSourceFile="..\Graphics\ApplicationLogo.ico">
<Variable Name="InstallFolder" Type="string" Value="" />
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLargeLicense">
<bal:WixStandardBootstrapperApplication LicenseFile="..\MyApp\EULA.rtf" LogoFile="..\Graphics\InstallerLogo_64.png" ShowVersion="yes" ShowFilesInUse="yes" />
</BootstrapperApplicationRef>
<Chain>
<MsiPackage Id="x86" InstallCondition="NOT VersionNT64" SourceFile="$(var.WiXSetup x86.TargetDir)MyAppSetup_x86.msi">
<MsiProperty Name="INSTALLFOLDER" Value="[InstallFolder]" />
</MsiPackage>
<MsiPackage Id="x64" InstallCondition="VersionNT64" SourceFile="$(var.WiXSetup x64.TargetDir)MyAppSetup_x64.msi">
<MsiProperty Name="INSTALLFOLDER" Value="[InstallFolder]" />
</MsiPackage>
</Chain>
</Bundle>
</Wix>

Related

Wix toolset. Cannot remove app. When I run uninstall, started install

When I want to uninstall the app, but show the install view.
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<Bundle Name="NAME" Version="1.1.25.2" Manufacturer="NAME" UpgradeCode="ID">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.HyperlinkLicense">
<bal:WixStandardBootstrapperApplication SuppressOptionsUI="yes" SuppressRepair="yes" LicenseUrl="" />
</BootstrapperApplicationRef>
<Chain>
<MsiPackage Id="iis" SourceFile="$(TargetPath)" DisplayInternalUI="no" Permanent="yes"/>
<!--<ExePackage Id="hosting" SourceFile="dotnet-hosting-6.0.4-win.exe" DownloadUrl="https://download.visualstudio.microsoft.com/download/pr/0c2039d2-0072-43a8-bb20-766b9a91d001/0e2288a2f07743e63778416b2367bb88/dotnet-hosting-6.0.4-win.exe" InstallCommand="/install /quiet" Compressed="no" Permanent="yes"/>-->
<MsiPackage Id="rewrite" SourceFile="rewrite_amd64_en-US.msi" DownloadUrl="https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_en-US.msi" Permanent="yes" DisplayInternalUI="no"/>
<MsiPackage Id="server" SourceFile="$(TargetPath)" DisplayInternalUI="yes" Vital="yes"/>
</Chain>
</Bundle>
</Wix>

WIX; How can I pass the [installfolder] as argument in an ExePackage

I am creating a WIX bundle which calls an executable.
In that call I'm trying to pass the installfolder as an argument but for some reason this doesn't seem to work.
The bundle:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle Name="$(var.Department) $(var.ProductName)"
Version="!(bind.packageVersion.Database.CLI.Verify)"
Manufacturer="$(var.Company) $(var.Department)"
UpgradeCode="5fc4dc21-0202-4e28-b8a4-b87f972ae32e"
DisableRemove="yes"
DisableModify="yes"
IconSourceFile="Database.ico">
<util:RegistrySearchRef Id='VerifyDotnetVersion' />
<Variable Name="InstallFolder" Type="string" Value="c:\$(var.Company)"/>
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.HyperlinkLicense">
<!-- LicenseUrl intentionally empty. -->
<bal:WixStandardBootstrapperApplication LicenseUrl=""
LogoFile="Database.png"
SuppressOptionsUI="no"
SuppressRepair="yes"/>
</BootstrapperApplicationRef>
<Chain>
<PackageGroupRef Id="SqlServer2019ExpressLocalDB" />
<PackageGroupRef Id="Database.CLI"/>
</Chain>
</Bundle>
<Fragment>
<util:FileSearch Id='VerifyDotnetVersion'
Variable="DotnetVersion"
Path="dotnet.exe"
Result="version" />
<bal:Condition Message="This installer requires at least dotnet version 6.">
DotnetVersion >= v6
</bal:Condition>
</Fragment>
</Wix>
And the part that is calling the ExePackage:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Fragment>
<PackageGroup Id="Database.CLI">
<ExePackage Id="Database.CLI.Verify"
DisplayName="Check whether SqlLocalDb has been installed."
SourceFile="$(var.SourceFile)"
InstallCommand="verify"
UninstallCommand="remove"
Vital="yes"
Compressed="no"
PerMachine="yes"
Permanent="no">
<ExitCode Value="0" Behavior="success" />
<ExitCode Value="1" Behavior="error" />
<ExitCode Value="5" Behavior="error" />
<ExitCode Value="31" Behavior="error" />
<ExitCode Value="183" Behavior="success" />
<ExitCode Value="574" Behavior="error" />
<ExitCode Value="3010" Behavior="forceReboot" />
</ExePackage>
<ExePackage Id="Database.CLI.Attach"
DisplayName="Attach database to the SqlLocalDb instance."
SourceFile="$(var.SourceFile)"
InstallCommand="attach Target="[INSTALLFOLDER]\$(var.Department)\$(var.ProductName)""
Vital="yes"
Compressed="no"
PerMachine="yes">
<ExitCode Value="0" Behavior="success" />
<ExitCode Value="1" Behavior="error" />
<ExitCode Value="5" Behavior="error" />
<ExitCode Value="31" Behavior="error" />
<ExitCode Value="183" Behavior="success" />
<ExitCode Value="574" Behavior="error" />
<ExitCode Value="3010" Behavior="forceReboot" />
</ExePackage>
</PackageGroup>
</Fragment>
</Wix>
When I look in the logs I see as argument:
[7A60:546C][2022-06-16T16:44:15]i301: Applying execute package: Database.CLI.Attach, action: Install, path: C:\ProgramData\Package Cache\0FD93FB1FD9BBE5B46CC123351ECE9DBCEC54E9D\Database.CLI.exe, arguments: '"C:\ProgramData\Package Cache\0FD93FB1FD9BBE5B46CC123351ECE9DBCEC54E9D\Database.CLI.exe" attach Target="\Analytics\Database"'
But I'm missing the contents of the [INSTALLFOLDER] so what I expect should be something like Target="c:\temp\Analytics\Database".
What am I missing here?
p.s. Is it also possible to provide an INSTALLFOLDER when launching the setup-bundle for silent installs? Like Database.Setup.exe InstallLocation=c:\temp
Many thanks in advance.
Burn variables are case-sensitive, so use [InstallFolder], not [INSTALLFOLDER].

WiX Uninstall functionality with StandardBootstrapperApplication

I've built a very basic installer for a bundle of applications with dependencies and that handles a restart for a .NET package. What I'm running into now, however, is the problem where the uninstall action only uninstalls the installer itself, which shows up in the program list. All of the other .exe files that run installation processes remain installed. Is there any simple way to handle this installation? I'm still very new to the WiX toolset and didn't want to dive really deep into a custom installer. Here is my bundle:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle Name="Visible EP Installer" Version="1.0.0.0" Manufacturer="VEP" UpgradeCode="8d1a4e2a-be3f-4b51-824b-75652ae98bad">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" >
<bal:WixStandardBootstrapperApplication
LicenseFile="..\VisibleEP EULA-ver2.rtf"
LogoFile="..\VEPLogo_HeartOnlyBlack(50x50).png"
/>
</BootstrapperApplicationRef>
<?define NetFx45MinRelease = 378389?>
<util:RegistrySearch
Id="NETFRAMEWORK45"
Variable="NETFRAMEWORK45"
Root="HKLM"
Key="SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"
Value="Release"
Result="value" />
<Chain>
<ExePackage Id="NetFx45Redist" Cache="no" Compressed="yes" PerMachine="yes" Permanent="yes" Vital="yes" InstallCommand="/q /norestart" RepairCommand="/q"
SourceFile="..\VEP Deploy\Setup Files\dotNetFx45_Full_setup.exe"
DetectCondition="NETFRAMEWORK45 >= $(var.NetFx45MinRelease)"
InstallCondition="(NOT NETFRAMEWORK45 >= $(var.NetFx45MinRelease))">
<ExitCode Value="1641" Behavior="forceReboot"/>
<ExitCode Value="3010" Behavior="forceReboot"/>
<ExitCode Value="0" Behavior="success"/>
<ExitCode Behavior="error"/>
</ExePackage>
<ExePackage
SourceFile="..\VEP Deploy\Setup Files\Encoder_en.exe"
Permanent="no"
InstallCommand="/q"
RepairCommand="/q">
<ExitCode Behavior="success"/>
</ExePackage>
<ExePackage
SourceFile="..\VEP Deploy\Setup Files\vcredist_x86.exe"
Permanent="no"
InstallCommand="/q"
RepairCommand="/q">
<ExitCode Behavior="success"/>
</ExePackage>
<ExePackage
SourceFile="..\VEP Deploy\Setup Files\vcredist_x64.exe"
Permanent="no"
InstallCommand="/q"
RepairCommand="/q">
<ExitCode Behavior="success"/>
</ExePackage>
<ExePackage
SourceFile="..\VEP Deploy\Setup Files\vep_setup.exe"
Permanent="no">
<ExitCode Behavior="success"/>
</ExePackage>
</Chain>
</Bundle>
</Wix>
I know that handling the exit codes for the last few is a bit hackish but I'm not all that concerned with that at the moment so long as it isn't impacting my other problem.
You have to supply UninstallCommand attribute values so Burn knows how to uninstall the .exes.

How to determine whether dotnet and VSTORuntime is installed in WIX Bootstrapper

i made a setup file of my Add-Ins project using wix. it has some dependencies like dotNet and VSTO Runtime. so I used Wix bootstrapper to confirm that dependencies must be installed before installing the product it works too. But i need conditional installation of dependencies like if dotNet and VSTO runtime is installed then don't look for install these items. i tried the registry searches too but didn't get success, here is my bootstrapper code tell me where i need to modify my code.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle Name="FinalSetup" Version="1.0.0.0" Manufacturer="Ramesh" UpgradeCode="5704ca64-b7bc-487b-8867-cabb51621c0e">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" >
<bal:WixStandardBootstrapperApplication LicenseFile="mylicense.rtf"
SuppressOptionsUI="yes" />
</BootstrapperApplicationRef>
<Chain>
<ExePackage Id="dotNetFx40_Full_x86_x64" SourceFile="dotNetFx40_Full_x86_x64.exe" PerMachine="yes" Cache="no"
Compressed="no"
DownloadUrl="http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe"
Permanent="yes"
InstallCommand="/q /norestart"
DetectCondition="VSTOR40_Installed"
InstallCondition="1" />
<ExePackage Id="VSTORuntime" SourceFile="vstor_redist.exe" Permanent="yes" Vital="yes" Cache="no" Compressed="no"
DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=158917"
PerMachine="yes"
InstallCommand="/q /norestart"
DetectCondition="VSTOR40_Installed"
InstallCondition="NOT VSTOR40_Installed" />
<MsiPackage SourceFile="$(var.Setup.TargetPath)" Vital="yes" Compressed="yes" Id="WordAddIns" After="VSTORuntime"/>
</Chain>
</Bundle>
</Wix>
Another issue i have is, i attached the mylicense.rft which has some dummy contents. but setup doesn't show the license content during installation process, look at the attached snapshot
The issue was I forget to use value attribute which causes this problem. This was problem with rtf file, after changing the file it worked as expected.
Here is the working version of code.
Working version is here
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle Name="FinalSetup" Version="1.0.0.0" Manufacturer="Ramesh" UpgradeCode="5704ca64-b7bc-487b-8867-cabb51621c0e">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" >
<bal:WixStandardBootstrapperApplication LicenseFile="mylicense.rtf"
SuppressOptionsUI="yes" />
</BootstrapperApplicationRef>
<util:RegistrySearch Id="VSTORuntimeTest" Root="HKLM" Key="SOFTWARE\Microsoft\VSTO Runtime Setup\v4R\" Value="VSTORFeature_CLR40" Variable="VSTORFeature"/>
<util:RegistrySearch Id="VSTORuntimeVersionV4R" Root="HKLM" Key="SOFTWARE\Microsoft\VSTO Runtime Setup\v4R\" Value="Version" Variable="VSTORVersionV4R"/>
<util:RegistrySearch Id="VSTORuntimeVersionV4" Root="HKLM" Key="SOFTWARE\Microsoft\VSTO Runtime Setup\v4\" Value="Version" Variable="VSTORVersionV4"/>
<util:RegistrySearch Id="DotNetTest" Root="HKLM" Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full" Value="Install" Variable="DotNetInstall"/>
<util:RegistrySearch Id="DotNetVersion" Root="HKLM" Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full" Value="Version" Variable="DotNetVersion"/>
<Chain>
<ExePackage Id="dotNetFx40_Full_x86_x64" SourceFile="dotNetFx40_Full_x86_x64.exe" PerMachine="yes" Cache="no"
Compressed="no"
DownloadUrl="http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe"
Permanent="yes"
InstallCommand="/q /norestart"
DetectCondition="NOT DotNetInstall"
InstallCondition="NOT DotNetInstall OR NOT (DotNetVersion >=v4.0.30319)" />
<ExePackage Id="VSTORuntime" SourceFile="vstor_redist.exe" Permanent="yes" Vital="yes" Cache="no" Compressed="no"
DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=158917"
PerMachine="yes"
InstallCommand="/q /norestart"
DetectCondition="VSTORFeature"
InstallCondition="NOT VSTORFeature OR NOT (VSTORVersionV4R >=v10.0.40303) OR NOT (VSTORVersionV4 >=v10.0.21022)" />
<MsiPackage SourceFile="$(var.Setup.TargetPath)" Vital="yes" Compressed="yes" Id="WordAddIns"/>
</Chain>
</Bundle>
</Wix>

WiX Extended Bootstrapper Application: How to determine which radio button is selected?

Here's my setup:
Compiling at .NET 4.0 (this cannot change)
Using WiX 3.7
Using the WiX Extended Bootstrapper Application extension
So I'm creating a bootstrapper installation project and though I've got it working, I feel like there is a much more clean and easy way to do it.
Basically, I need to have the user select which environment they wish to use when they install the product. To do this, I use the WiX Extended Bootstrapper Application extension to allow me to put some radio buttons on the first install screen.
Getting that all setup was fine, but then I realized that I don't know how to easily determine which radio button has been selected. So as I work around I just listed the MSI three times in the bundle and put install conditions on each one.
Is there a way to determine which radio button has been selected with just one property? (For example, when I pass the InstallFolder property to my MSI as seen in the code below.) And if there isn't a way to do this currently, is there a way for me to do this without adding my MSI three times to the bundle?
Here's my code (Notice how I list essentially the same MsiPackage three times):
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<?include Properties.wxi ?>
<Bundle Name="!(loc.Product.Name)" Version="$(var.Version)" Manufacturer="!(loc.Product.Manufacturer)" UpgradeCode="$(var.UpgradeCode)" Condition="VersionNT >= v5.1">
<BootstrapperApplicationRef Id="WixExtendedBootstrapperApplication.Hyperlink2License">
<bal:WixExtendedBootstrapperApplication SuppressRepair="yes" LicenseUrl="" ThemeFile="$(var.Bundle.ExtTheme.RadioBtns.Path)" LocalizationFile="$(var.Bundle.ExtTheme.RadioBtns.l10n.Path)" />
</BootstrapperApplicationRef>
<WixVariable Id="WixMbaPrereqPackageId" Value="Netfx4Full" />
<Variable Name="InstallFolder" Type="string" Value="$(var.InstallFolder.Value)" />
<Variable Name="RadioButton1" Type="numeric" Value="0" />
<Variable Name="RadioButton2" Type="numeric" Value="0" />
<Variable Name="RadioButton3" Type="numeric" Value="1" />
<Chain>
<!-- Other Package References Here -->
<MsiPackage Id="DBConnections_Dev"
SourceFile="$(var.MSI.Path)"
Visible="no"
Vital="yes"
InstallCondition="RadioButton1 = 1">
<MsiProperty Name="INSTALLFOLDER" Value="[InstallFolder]" />
<MsiProperty Name="SELECTED_ENV" Value="1" />
</MsiPackage>
<MsiPackage Id="DBConnections_Stage"
SourceFile="$(var.MSI.Path)"
Visible="no"
Vital="yes"
InstallCondition="RadioButton2 = 1">
<MsiProperty Name="INSTALLFOLDER" Value="[InstallFolder]" />
<MsiProperty Name="SELECTED_ENV" Value="2" />
</MsiPackage>
<MsiPackage Id="DBConnections_Prod"
SourceFile="$(var.MSI.Path)"
Visible="no"
Vital="yes"
InstallCondition="RadioButton3 = 1">
<MsiProperty Name="INSTALLFOLDER" Value="[InstallFolder]" />
<MsiProperty Name="SELECTED_ENV" Value="3" />
</MsiPackage>
</Chain>
</Bundle>
</Wix>
I also asked this question on the project's CodePlex site and the developer responded as follows (here is a link to the full discussion: http://wixextba.codeplex.com/discussions/432341):
This can now be done using the custom actions feature.
I've tested his response and found it to be correct! This functionality is available as of version 3.7.4791.32058. There is also an example included in the source code demonstrating how this is done. I've posted the pertinent code below:
Needed in Custom Action c++ code:
STDMETHODIMP OnPlanCustomAction()
{
...
if (SUCCEEDED(BalGetNumericVariable(L"RadioButton1", &llValue)) && llValue)
{
m_pEngine->SetVariableNumeric(L"RadioButton", 1);
BalExitOnFailure(hr, "Failed to set variable.");
}
else if (SUCCEEDED(BalGetNumericVariable(L"RadioButton2", &llValue)) && llValue)
{
m_pEngine->SetVariableNumeric(L"RadioButton", 2);
BalExitOnFailure(hr, "Failed to set variable.");
}
else if (SUCCEEDED(BalGetNumericVariable(L"RadioButton3", &llValue)) && llValue)
{
m_pEngine->SetVariableNumeric(L"RadioButton", 3);
BalExitOnFailure(hr, "Failed to set variable.");
}
else if (SUCCEEDED(BalGetNumericVariable(L"RadioButton4", &llValue)) && llValue)
{
m_pEngine->SetVariableNumeric(L"RadioButton", 4);
BalExitOnFailure(hr, "Failed to set variable.");
}
else
{
m_pEngine->SetVariableNumeric(L"RadioButton", 0);
BalExitOnFailure(hr, "Failed to set variable.");
}
...
Needed in WiX XML (from examples that come with downloaded DLL):
<Variable Name="RadioButton1" Type="numeric" Value="0" />
<Variable Name="RadioButton2" Type="numeric" Value="1" />
<Variable Name="RadioButton3" Type="numeric" Value="0" />
<Variable Name="RadioButton4" Type="numeric" Value="0" />
<Chain DisableSystemRestore="yes">
<PackageGroupRef Id="NetFx40Redist" />
<MsiPackage
Id="Setup"
Compressed="yes"
SourceFile="Setup.msi"
Vital="yes">
<MsiProperty Name="APPLICATIONFOLDER" Value="[InstallFolder]" />
<MsiProperty Name="RadioButton" Value="[RadioButton]" />
</MsiPackage>
</Chain>
Check out the links in the text for the original examples from which these code samples were taken. Hope this helps others in the future.