Migrating from Wix 2 to Wix 3: Duplicate Symbols - wix

I am totally new to WiX, so of course my first task with WiX is to migrate an existing large installation program from WiX 2 to WiX 3. I've had a number of wrinkles most of which have been sorted, but I would be grateful for some suggestions with the following light errors. Since I am new to WiX, I want to list my whole process:
To create a WiX library:
candle.exe *.wxs
lit.exe -out "wixui_company.wixlib" *.wixobj
To generate the main MSI:
candle.exe main.wxs -o main.wixobj
light.exe main.wixobj -o Main_Installer.msi wixui_company.wixlib -ext WixUIExtension
This last command gives dozens and dozens of errors, but they all take the following form
error LGHT0091 : Duplicate symbol 'Dialog:LicenseAgreementDlg' found.
I have grep and re-greped, but the only references are the following:
In LicenseAgreementDlg.wxs:
<Fragment>
<UI>
<Dialog Id="LicenseAgreementDlg" ...
And in wixui_company.wxs
<Fragment>
<UI Id="WixUI">
<DialogRef Id="LicenseAgreementDlg" />
...
<Property Id="WixUI_WelcomeDlg_Next" Value="LicenseAgreementDlg" />
It is the DialogRef line that gives the error.
These both get referenced from wixui_company.wixlib in the main.wxs:
<UIRef Id="WixUI" />
FWIW, if I change either the ref to WixUI or the ref to LicenseAgreementDlg, duplicate errors go away, but instead I get symbol not found link errors. I migrated the original wxs files using WixCop, but under WiX 2 they all worked as is. I am guessing that this has to do with the move to put WiXUI in it's own namespace in WiX 3, but frankly I have no idea what to even try.
Any ideas on where things went horribly wrong?
Thanks,
Adam

"LicenseAgreementDlg" is the name of a dialog in the WixUIExtension that you're linking to with light.exe. Every dialog in an MSI database must have a unique identifier, so it's likely you've made a <UIRef> element to one of the standard WiX UIs ("WixUI_FeatureTree", "WixUI_Mondo", etc.), which includes WiX's LicenseAgreeementDlg dialog. You're then referencing your own LicenseAgreementDlg, so now you have two dialogs with the same name.
In this situation, you'd need to either rename your own LicenseAgreementDlg or remove it altogether and use the built-in one.

Related

Wix burn doesn't allow to remove file

I'm creating a bootsrapper and I want to remove links that are created during installation. So I write following step:
<Chain>
...
<ExePackage Id="removelnk" Cache="no" SourceFile="run.bat" InstallCommand="del "C:\Users\Public\Desktop\Parity UI.lnk"" />
</Chain>
Where run.bat is simply %* which allows to run arbitrary code as described here.
However, it doesn't work:
[19EC:0E2C][2018-06-16T18:32:27]i301: Applying execute package: removelnk, action: Install, path: C:\ProgramData\Package Cache\1608BB75347CD8C40187E5F3C0A969ED73A98D51\run.bat, arguments: '"C:\ProgramData\Package Cache\1608BB75347CD8C40187E5F3C0A969ED73A98D51\run.bat" del "C:\Users\Public\Desktop\Parity UI.lnk"'
[19EC:0E2C][2018-06-16T18:32:27]e000: Error 0x80070001: Process returned error: 0x1
[19EC:0E2C][2018-06-16T18:32:27]e000: Error 0x80070001: Failed to execute EXE package.
[0AE4:2B94][2018-06-16T18:32:27]e000: Error 0x80070001: Failed to configure per-machine EXE package.
[0AE4:2B94][2018-06-16T18:32:27]i319: Applied execute package: removelnk, result: 0x80070001, restart: None
[0AE4:2B94][2018-06-16T18:32:27]e000: Error 0x80070001: Failed to execute EXE package.
If I execute this command from log in my cmd then it works as expected. It even works without admin privileges.
What's wrong here?
Creating a Transform: You can use a transform to modify any MSI file - a very common use for a transform is to remove such shortcuts. You should be able to apply that transform on the command line specified in your bootstrapper - though I have never tried this with WiX bootstrappers.
Transforms are "little database fragments" that are applied to the original MSI. It changes the MSI file in memory and you can pretty much change whatever you want. You can create transforms with Orca or an equivalent free tool. Commercial tools - such as Advanced Installer - can also be used of course. In fact they have a nice little video showing the process (towards the bottom).
There is a long explanation of transforms (among other things) here: How to make better use of MSI files.
Applying a Transform: You apply transforms via the Transforms property during installation.
Quick Sample Command Line:
msiexec.exe /I "My.msi" /QN /L*V "C:\My.log" TRANSFORMS="C:\1031.mst;C:\My.mst"
Quick Parameter Explanation:
/I = run installation sequence
/QN = run completely silently
/L*V "C:\My.log"= verbose logging
TRANSFORMS="C:\1031.mst;C:\My.mst" = Apply transforms 1031.mst and My.mst.
Burn Bundle Details: I have not tried applying a transform in a Burn bundle (so I should have the sense not to answer), but the MsiPackage element is what you need I believe. I found this rather complicated sample of a Burn bundle source file - perhaps it is worth a look? It seems the magic is in the MsiProperty child element for the MsiPackage element.
UPDATE:
Burn Hello-World Style Example: Finally got to run a quick test on a Windows computer (was on a Linux one). Here is how you can apply a transform via Burn (minimal sample, just intended to show the basics, not pretending to be good markup).
Just inlining the warning: I hear some rumors that the application of
the transform in this way might not work in all cases - such as
repair. Please test thoroughly. It worked for my test. Also test upgrade scenarios (major upgrade for example).
This will apply the transform ShortcutDesktop.mst to the original MSI ShortcutDesktop.msi:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<!-- Maybe generate yourself an Upgrade-GUID here: https://www.guidgenerator.com/ -->
<Bundle Name="MyCoolTestApp" Version="1.0.0.0" Manufacturer="Someone"
UpgradeCode="PUT-GUID-HERE">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
<MsiPackage SourceFile="ShortcutDesktop.msi">
<MsiProperty Name="TRANSFORMS" Value="ShortcutDesktop.mst" />
</MsiPackage>
</Chain>
</Bundle>
</Wix>
To build the Burn bundle BurnTest.wxs above:
set SetupName=BurnTest
candle.exe %SetupName%.wxs -ext WixBalExtension >> %SetupName%.log
light.exe %SetupName%.wixobj -ext WixBalExtension >> %SetupName%.log
And a link to a better Burn example on github:
https://github.com/frederiksen/Classic-WiX-Burn-Theme
Burn doesn't support batch files. Everything that modifies the machine should be done in a package.

WIX installer shows brackets in status line

I am using a WIX installer that is showing some brackets in the status line (see image below):
I haven't made changes to the WIX file, but only the installed files have changed. I did update WIX to v3.11, because this was required to use WIX in Visual Studio 2017. We use the standard WixUI.
These strings are listed in the C:\Program Files (x86)\WiX Toolset v3.11\SDK\wixui\WixUI_en-us.wxl file. A few lines from this file:
<String Id="ProgressTextRemoveFiles" Overridable="yes"><!-- _locID_text="ProgressTextRemoveFiles" _locComment="ProgressTextRemoveFiles" -->Removing files</String>
<String Id="ProgressTextRemoveFilesTemplate" Overridable="yes"><!-- _locID_text="ProgressTextRemoveFilesTemplate" _locComment="ProgressTextRemoveFilesTemplate" -->File: [1], Directory: [9]</String>
These strings exactly match what I see during installation. It seems only the ProgressDlg has this issue, but maybe other strings don't use expansion. Anyone has a clue?
Try to add the following line in your main wxs:
<UIRef Id="WixUI_ErrorProgressText" />
See my answer for the same question.

How to work with HEAT.exe for dll registry

and i need to register a dll . Right now am registering the dll as below
<CustomAction Id='comReg' Directory='INSTALLLOCATION' Impersonate='no' Execute='deferred'
ExeCommand='"[NETFRAMEWORK40CLIENTINSTALLROOTDIR]regasm.exe" "[INSTALLLOCATION]myProduct.dll" /codebase' Return='check' />
but all are suggesting to use HEAT.exe in internet wherever and whenever i surf . I even have gone through this link. But there they have only the syntax etc. I really dont know how to work with it just by knowing those syntax.
I need some step by step procedure or some good blog which elaborately tell how how to harvest a dll and how to impllement it in to wix code and how the registry will be done , so that i can register my dll based on conditions also.Even i tried this link alse
Regards
Registering a COM component is done through standard Windows Installer actions and tables. Numerous table entries are required so WiX provides heat.exe to harvest COM files. It works by inspecting a file for type libraries and, if the DllRegisterServer entry point is present, running it in a Registry sandbox where changes are intercepted and captured. (In the era of Windows Installer [1999-present], DllRegisterServer is effectively deprecated for any other purpose.)
As you may know, a Feature is the smallest user-selectable unit of installation. A Component is a member of one or Features in one or more Products. Heat creates a component for each file it harvests and a ComponenentGroup for each harvest run. So, you have to pick a ComponentGroup Id and reference it in one or more Features. You also have to pick a Directory Id for the destination of the ComponentGroup.
Now, it is simply a matter of editing your project file to harvest the file. To edit a project file you could use a text editor but Visual Studio is all set up for it. See How to: Edit Project Files.
Add a HarvestFile element to a new or existing ItemGroup, entering the desired ComponentGroup Id and Directory Id
<ItemGroup>
<HarvestFile Include="comserver.dll">
<ComponentGroupName>COM</ComponentGroupName>
<DirectoryRefId>ServerDir</DirectoryRefId>
</HarvestFile>
</ItemGroup>
In your Product.wxs or elsewhere, add a ComponentGroupRef to one or more Features.

Wix 3.6 Burn: unmanaged custom UI

I want to package multiple MSIs into a single install package, hence I am using Burn from Wix3.6.
I want to have a simple user interface allowing to select which package(s) should be installed.
I understand the standard BA (wixstdba.dll) does not provide this functionnality and that I need to write my own BA.
I have been looking at project 'wixstdba' from the 'wix36-sources' package as an example of a C++ BA. To get started I have tried simply rebuilding the project and adding the resulting DLL to my Bundle as follows:
<Bundle
Name="$(var.ProductName)"
Version="$(var.ProductVersion)"
Manufacturer="$(var.VendorName)"
UpgradeCode="$(var.UpgradeCode)" >
<BootstrapperApplication SourceFile="wixstdba.dll" />
<Chain>
...
I succesfully built the Bundle:
light -ext WixBalExtension.dll -ext WixUIExtension -ext WixUtilExtension installer-v$(VERSION).wixobj -o installer-v$(VERSION).exe
candle -o installer-v$(VERSION).wixobj bundle.wxs -d"Platform=x64"
However, when I run the resulting .exe, nothing happens. No UI appears, no software is installed and no error message.
Any idea what I might be doing wrong?
When you run the .exe, it should create a log file in your system's %TEMP% folder. This should tell you if any errors are being encountered. The file name will be the product name (with spaces replaced with underscores). The easiest way to find it is to open a Windows Explorer window, type "%TEMP%" for the folder name, and sort by Date Modified desc. The top file is likely the right one.
It is likely that the bootstrapper is running, but when it attempts to load your code it is unable to load some dependency, or otherwise has some error. Hopefully, the log will provide enough hints for you to find the issue.
If you end up needing to add additional libraries/files to be used by your BA, add them to the bundle payload files, like this:
<BootstrapperApplicationRef SourceFile="wixstdba.dll" >
<Payload SourceFile="$(var.ReferencedProject.TargetDir)\file.needed.at.runtime" />
</BootstrapperApplicationRef>
This will place the file in the same folder as your unpacked BA at runtime.

How do I import built-in Wix Dialogs?

I've inherited a Wix project. I don't know how it was compiled before, all I have are the source .wxs and .wxi files. I'm using candle and light from the command line to compile and link.
So far, I can candle my wxs files to wixobj files without error, however when I try and run light, I get a lot of errors similar to:
C:\wix\FeatureTree.wxs(39) : error LGHT0094 : Unresolved reference
to symbol 'Dialog:ErrorDlg' in
section 'Fragment:'.
I've done some reading, and it seems that the line that's causing this error:
<DialogRef Id="ErrorDlg" />
I've got the following line at the top of the Fragment:
<UIRef Id="WixUI_Common" />
Is just trying to import a built-in Wix error dialog. Why is it failing?
I was missing the library from the light command, which needs to be specified with -ext:
light -ext WixUIExtension *.wixobj -o installer.msi
Or from Visual Studio Wix project, add a reference to WixUIExtension.dll