Wix msi updated property value not working during installation - wix

Working with Wix in Visual Studio. I have a public property defined in Product node of wxs file.
<Property Id="MYPROP" Value="123456789"/>
The property value is passed as commandline argument to a deferred custom action executable. I'm able to receive it in the exe as well. The problem is even if I update the Property using vbs (verified through vbs select as well), when I launch the msi, it still passes the default/original value (123456789) to the custom action executable.
Also tried msiexec.exe /i myinstaller.msi MYPROP=SomeOtherValue
I'm still seeing the original value. What's wrong?

Maybe try this simple thing first:
<Property Id="MYPROP" Secure="yes" Value="123456789"/>
Essentially you need to add a property to the SecureCustomProperties list to have them pass properly to deferred mode in secure desktop environments.
See more information on SecureCustomProperties here. The technical details here are a little bit in flux because of Windows changes, so please just try this first - there could be several other reasons.
How do you use this property? What does it do?

When an msi is run, windows caches the msi file in %windows%\Installer folder. When that msi is run again, windows checks if an msi with identical PackageCode exists in the cache, if so then it uses the cached msi file instead.
PackageCode: identifies each unqiue msi installer package - even if it only has different properties.
In short, when a property is updated using a vbscript etc, then the PackageCode has to be updated as well. This will ensure that after updating msi, the same msi can be used on the same system and windows will not use the cached msi.

Related

Restrict WiX MSI From Running On Its Own

In my company I create apps that are shared by many different products. For instance a help application.
A requirement is that I create an MSI with WiX that can be consumed by the main installers for each product. This MSI receives variables from the main installers so that it installs and uninstalls properly.
Because of this, I want to restrict having the MSI run by itself. That is, someone double clicking on it, etc.
Is there a way I can prevent it from running on its own and display a message of some type to the user?
I am completely new to WiX and I really appreciate your help.
You can set a public property which blocks the installation of the product by default - i.e. if a user were to attempt to install it by double-clicking.
<Condition Message="test">BLOCKINSTALL = 1</Condition>
<Property Id="BLOCKINSTALL" Value="0"/>
This blocks install by default. The property can then be changed by your other installers, or by calling:
msiexec /package Installer.msi BLOCKINSTALL=1
This will allow you to change the blocking value, allowing the installation to progress.

WiX Burn: Create custom log file name for MsiPackage?

When Burn runs an MSI installer, using MsiPackage, I'd like the MSI's log file to have a custom name, like MyProductName.log. I'd also like to append to an existing log file (with same name).
In InstallShield's Basic MSI Project's Release view there is an entry "MSI Command-Line Arguments" where you can enter a custom log file name:
/l+* "%TEMP%\MyProductName.log"
The "+" will append the log to an existing file.
Burn can pass public properties to the MSI, but I don't see a way to do what I want.
It looks like I'll need to write code (custom Burn bootstrapper) to run after the MsiPackage is installed (or uninstalled) to copy the contents of the log file (in the Burn variable defined in LogPathVariable) to the file with the custom name.
You can use the LogPathVariable attribute of the MsiPackage element to provide a custom log file name ...
See: http://wixtoolset.org/documentation/manual/v3/xsd/wix/msipackage.html
Also: https://support.firegiant.com/hc/en-us/articles/230912207-Pass-Properties-to-MsiPackage-from-Bundle-
To do what I needed, I wrote a simple bootstrapper, which became more complicated as I addressed things like passing installer properties to the bootstrapper, giving warnings if installing an x86 installer on an x64 OS (we encourage customers to use and x64 installer), etc.

WiX repair from managed bootstrapper fails to fix some corrupted DLLs

I have a WiX Managed Bootstrapper Application that installs some MSIs. I also have a series of tests that exercise the various functions of the installer. The problem I'm having is with the repair test. The test purposely corrupts all the DLLs we install then calls the EXE installer with "/repair /passive" flags. Once completed around 80% of the DLLs are repaired but the remaining ones are untouched and therefore still corrupted after the repair.
If I manually run msiexec on an individual MSI with the command line args "/fa" which instructs the MSI to forcibly replace all the files it installed, it fixes 100% of the DLLs.
My question is how can I force the MBA to instruct each MSI to repair in this way? I've tried setting the REINSTALLMODE property to 'amus' on the individual MSIs in their .wxs files but the MBA overwrites them at run time as is evident in the log via this line:
PROPERTY CHANGE: Modifying REINSTALLMODE property. Its current value is 'amus'. Its new value: 'cmuse'.
I've also tried to set the properties in the MBA to pass through to each MSI but it doesn't appear to pass them and instead uses it's default values.
I see many similar questions here but none actually address this specific issue. Any help would be greatly appreciated. Rob save me!
Here's your problem right here:
[12:25:25:874]: File: C:****\estimator.dll; Won't Overwrite; Won't patch; Existing file is unversioned but modified
The installer doesn't want to overwrite a file that has changed since it was installed if it cannot verify the version or language (and maybe some other properties?). Without these properties, it decides to look at the modified date. If it is newer than when it was first installed then it won't touch it assuming instead that something changed for a reason and reverting it will cause something to fail. (You can read more here)
One thing you can do in this case is use a Companion File
Set this attribute to make this file a companion child of another file. The installation state of a companion file depends not on its own file versioning information, but on the versioning of its companion parent. A file that is the key path for its component can not be a companion file (that means this attribute cannot be set if KeyPath="yes" for this file). The Version attribute cannot be set along with this attribute since companion files are not installed based on their own version.
Basically you will set the logic for installing/uninstalling this component to be the same as the "FileID" of another component in the install. In the estimator.dll component, in the File tag, remove KeyPath="yes" and instead replace that with CompanionFile="<NameOfAnotherFileID>".
The issue with this approach is that you may have a corrupted DLL but the companionFile it was linked to was fine so it is not reinstalled.
If this is a dll you do own, I would highly suggest versioning the file! Give it any version you want and this issue should go away.
Another thing you can try, although I don't know how it works really, is giving the file a DefaultVersion
This is the default version of this file. The linker will replace this value from the value in the file if the suppress files option is not used.
This would be the quickest solution to verify. Just build a new installer with DefaultVersion="1.0" in the estimator.dll's <File> and see if it gets replaced. I think this will have the installer think the file is versioned 1.0 but the installed file is not versioned so it will replace it (see here)

WIX Burn MSI Properties Being Overridden

I am building a WIX bootstrapper to call some pre-existing MSIs we have. The overall install is working and I can see in the log that I am able to successfully pass parameters from the BS to the MSI. However, I see in the log file that the parameters are then being overridden.
The MSI was created using the Visual Studio deployment project templates. In the UI, we pre-populate some of the entry fields with default values. So basically those defaults are overriding the values I am passing in from the bootstrapper. Can this be avoided?
It depends how you are setting the default values, but in your situation I would use a WiX SetProperty element to set the default values with a condition of Not PROPERTYNAME so that it won't be set if it's already set.

What is the usage of TARGETDIR and INSTALLDIR in WiX?

In legacy Visual Studio Deployment Project installers, passing a command-line parameter that specified a value for TARGETDIR allowed me to override the default installation location (most of my installations take place without user interaction, so command-line automation is used heavily). However, the impression I'm getting is that WiX (by default) uses TARGETDIR for something different. While I can (and will) update our command-line tools to change the parameter name, that still leaves all of our existing installations that would need to be touched manually (a non-trivial effort).
Is there any way to override the installation location in a WiX package by specifying TARGETDIR without breaking anything?
After doing more digging, it looks like my previous experience is a result of behavior specific to VSDPROJ's (and possibly InstallShield), wheras WiX is conforming to the Windows Installer.
As I discovered at this link, TARGETDIR is actually supposed to represent the root of the drive with the most free space available (assuming there's more than one). That's why WiX projects have directories nested under there for Program Files, etc. Visual Studio actually adds a custom action that overrides this property to the full installation path.
I was able to accomplish what I wanted by doing two things:
Change all of my components and component groups to install to TARGETDIR instead of INSTALLFOLDER (the default directory that WiX put in there)
Add a custom action that sets the value of the TARGETDIR property to the installation path, assuming one wasn't passed in from the command line.
To do that, I added this under the <Product> tag:
<CustomAction Id="SetTARGETDIR" Property="TARGETDIR"
Value="[ProgramFilesFolder][Manufacturer]\[ProductName]"
Execute="firstSequence" />
And this within the <InstallExecuteSequence> tag:
<Custom Action="SetTARGETDIR" Before="CostFinalize">TARGETDIR=""</Custom>