Set the Property value to an ini file WIX - wix

I was setting a property value inside a Dialog using Edit Control. But when i used the same property for writing inside an ini value it is not writing the updated value and writing only old value. My WIX source code is given below(writing only important codes as my wix code is too large)
<Property Id="testNumber" Value="1122" />
<CustomAction Id="SettestNumber" Property="ModifiedtestNumber" Value="[testNumber]" />
<ComponentGroup Id="INIFileGroup">
<Component Id="IniFile" Guid="{0ded271b-9268-49e7-8c13-60c7538acc25}" KeyPath="yes" Directory="DirCfg" >
<IniFile Id="IniPath" Action="addLine" Directory="Dirtest" Key="testkey" Name="test.ini" Section="test" Value="[ModifiedtestNumber]" />
</Component>
</ComponentGroup>
<InstallUISequence>
<Custom Action="SettestNumber" Sequence="1299"/>
</InstallUISequence>
<Dialog Id="testNumberUI" X="50" Y="50" Width="375" Height="270" Title="[ProductName]" CustomPalette="yes">
<Control Type="Edit" Id="test_Number" Width="50" Height="15" X="258" Y="53" Property="testNumber" Text="{50}" TabSkip="yes"/>
</Dialog>
I am giving the value 1212 in the Control edit box and installing but inside the test.ini file it is not getting updated and value is 1122. Could someone please provide a way for me to update the Modifedtestnumber to the ini file
Note:
When i put the Custom action inside < InstallExecuteSequence/> the value inside the ini file was null

Your property need to be public (all caps TESTNUMBER) and marked with Secure attribute so that it's listed in the SecureCustomPublicProperties property. Also be aware that properties are not persisted. You need to use something like the WiX remember property pattern for the value to be loaded from the INI file during subsequent transactions such as repairs and upgrades.

Related

WIX: Setting a registry value from a dialog checkbox

Using Wix for the first time in 10+ years, and first time with forms/dialog entry.
Have a property defined more or less like this:
<Property Id="THE_FLAG">
<RegistrySearch Id="SearchTheFlag" Root="HKLM" Key="SOFTWARE\$(var.Manufacturer)\$(var.SimpleProductName)" Name="the_flag" Win64="$(var.Win64)" Type="raw" />
</Property>
Have a control in a form to set it:
<Control Id="TheFlagCheckBox" Type="CheckBox" X="45" Y="80" Width="220" Height="17" Property="THE_FLAG" CheckBoxValue="1" Text="Flag for something" />
At the end I want to write it:
<RegistryKey Root='HKLM' Key='SOFTWARE\$(var.Manufacturer)\$(var.SimpleProductName)' ForceCreateOnInstall='yes' >
<RegistryValue Name='the_flag' Type ='integer' Value='[THE_FLAG]' />
</RegistryKey>
If I select the checkbox, it sets the registry value. However, if I don't check the checkbox, then I get a warning when running the installer about not being able to acces the registry value. I think it is because the "value" of "THE_FLAG" is null or the empty string. I want to avoid the nasty warning to the user. I took over some code, and the previous owner used all strings for obviously DWORD values...maybe to get around the warning.
Can I set some conditionals or set the value of THE_FLAG to "0" if it is "" or null?
Add the following to your authoring:
<SetProperty Id="THE_FLAG" Value="0" Before="InstallInitialize" Sequence="execute">NOT THE_FLAG</SetProperty>
This will set the value of THE_FLAG to "0" if it's blank (in MSI, null and empty string are both blank) before the registry writes are done. A reasonable alternate value for Before is "WriteRegistryValues".

how to get wix propery value to wix vb custom action project?

I am struggeling with this &%^&##$ problem for over two weeks and it is still not working. I need the user to input some data and that data needs to be sent to my WIX VB custom action project. however it does never reach it. I currently have the following code in WIX:
Input of the user:
<Control Id="InputField" Type="Edit" X="20" Y="100" Width="140" Height="18" Property="ValueAdaptionScript" Text="{40}"/>
Adding the DLL to the installer:
<ComponentGroup Id ="DLL" Directory ="INSTALLFOLDER">
<Component Id ="StringTransfer" Guid ="{479947FA-C324-411C-9B98-083E79C116CB}">
<File Id ="StringTransfer" KeyPath="yes" Source="C:\Users\fjansen\Documents\Visual Studio 2015\Projects\String Transfer\Data Transfer\obj\x86\Debug\DataTransfer.CA.dll" />
</Component>
</ComponentGroup>
The custom actions and the Binary to point towards the DLL:
<Binary Id="StringTransfer" SourceFile="C:\Users\fjansen\Documents\Visual Studio 2015\Projects\String Transfer\Data Transfer\obj\x86\Debug\DataTransfer.CA.dll" />
<CustomAction
Id="SetProperties"
Property="ValueAdaptionScript"
HideTarget="no"
Value="[MachineIdNumber]"
/>
<CustomAction
Id="ValueAdaptionScript"
BinaryKey="StringTransfer"
DllEntry="CustomAction1"
Execute="deferred"
Impersonate="no"
Return="check"
/>
<InstallExecuteSequence>
<Custom Action="SetProperties" Before="ValueAdaptionScript" />
<Custom Action="ValueAdaptionScript" Before="InstallFinalize">NOT REMOVE="ALL"</Custom>
</InstallExecuteSequence>
in the WIX custom action project I have made a function to write to a file so I can see what is being recieved from WIX. this is just to test the passing of values, if passing of the values work I adapt the code the let it replace a specific piece of text with the input from the user in a .INI file.
the code of the WIX custom action project:
Imports System.IO
Imports System.Reflection
Public Class CustomActions
Public Shared Property MachineIdNumber As String
Public Shared Property ValueAdaptionScript As String
<CustomAction()>
Public Shared Function CustomAction1(ByVal session As Session) As ActionResult
Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter("c:\test.txt", True)
file.WriteLine("test")
file.WriteLine(MachineIdNumber)
file.WriteLine(ValueAdaptionScript)
file.WriteLine(CustomAction1)
file.Close()
Return ActionResult.Success
End Function
End Class
when the installer is ran with all this code I do get a text file with the following content: text and 0. the first is logical since i hard coded it and the 0 is the product of CustomAction1 and means that the CustomAction has ended succesfull. that is all good and well, bud I don't get the value I would like to see.
I really need help with this, since I just don't get it working and have spent a huge amount of time on this problem. bud mainly since this is the last obstacle before I am able to deploy the installer.
Thanks in advance,
F.J
There are a few things incorrect here.
Properties passsed between the UI sequence and the execute sequence need to be all uppercase - that means they are public. They also should be declared first with Secure='yes'.
You don't declare propErties in your custom action code, you get them from the installation process. If your CA was immediate you'd say something like varname = session["VALIDATIONSCRIPT"] but it's deferred, so this is a good overview:
http://vadmyst.blogspot.com/2006/05/deferred-custom-actions-with-wix.html
and having set up the deferred CA property you'd use varname = session["CustomActionData"]
and this too:
https://www.firegiant.com/wix/tutorial/events-and-actions/at-a-later-stage/

How can I have a WiX Property default to null?

I am working on a set of WiX installers that are going to share a common form. Every application needs the values set, but they are going to be different for each application.
I am trying to allow for the properties (which are linked to controls) to have a default value (or not) and to allow for the property values to be set via command line.
in my "SharedDialog.wxs" I have:
<Fragment>
<PropertyRef Id="PROP1"/>
<PropertyRef Id="PROP2"/>
<UI>
<Dialog Id="SharedDialog" Width="370" Height="270" Title="[ProductName]">
<Control Type="Edit" Id="1" Property="PROP1" Wid... Indirect="no" />
<Control Type="CheckBox" Id="2" Property="PROP2" Wid...
CheckBoxValue="1" Indirect="no"/>
</Dialog>
</Fragment>
In a file for the application specific project:
<Fragment>
<Property Id="PROP1" Value="Test"/>
<Property Id="PROP2" Value="1"/>
</Fragment>
This all works for what I am trying to do, but the problem is that when I want to clear the values as so: (so they don't have a default)
<Fragment>
<Property Id="PROP1"/>
<Property Id="PROP2"/>
</Fragment>
I get this error:
Unresolved reference to symbol 'Property:PROP1' in section 'Fragment:'.
Unresolved reference to symbol 'Property:PROP2' in section 'Fragment:'.
WiX also will not let you set value to "". The problem is that as far I can tell the checkbox will always be checked if the property has a value. How can I set the property "PROP2" to "null"?
You can undefine an existing property by setting it equal to an empty string wrapped in braces like this: PROPERTY = {} in a set property custom action. This means the property doesn't exist, it is not an empty string. See the explanation here.
For properties to be available from the command line they must be PUBLIC - they are the properties that are all UPPERCASE.
Setting PUBLIC PROPERTIES secure means they can be passed from the client to the server installation process which is required for properties that are used in deferred mode custom actions. Technically this adds them to the list of SecureCustomProperties.
You can give PUBLIC PROPERTIES a default value in the Property table, and then set other values from the command line. The command line overrides the defaults:
msiexec.exe /I "C:\Test.msi" /QN /L*V "C:\log.log" TEST="MyValue" TEST2="MyValue"
See more info:
How to set a check box to "unchecked" from the msiexec command line?
Nevermind, I found the solution:
<Fragment>
<Property Id="PROP1" Secure="yes"/>
<Property Id="PROP2" Secure="yes"/>
</Fragment>

Storing Checkbox value in a Property Wix 3.7

Currently I am working on a simple project in which i have to modify an xml file using user input in WIX 3.7. Everything goes fine except in case of checkbox.
I have created a Property and then using that property in a checkbox type of control. I need that if the checkbox is checked then Node value will be modified to 1 and if not then 0.
Below is the code i have used.
<Property Id="ISPATH" Secure="yes"></Property>
<Control Id="checkBox1" Type="CheckBox" Height="18" Width="67" X="104" Y="108" Text="Is-Path" Property="ISPATH" CheckBoxValue="1" >
</Control>
<util:XmlFile Id="ModifyPath" Action="setValue" Permanent="yes" ElementPath="/DataBaseSettings/IsPath"
File="[#Settings]" Value="[ISPATH]" SelectionLanguage="XSLPattern" Sequence="1" />
No Change is seen in ISPATH property.
Any Suggestions????

How to inspect a CustomAction's property (Wix)?

I am trying to put together a small 'prerequisites' dialog in Wix to give confidence to the users that they have all of the required things needed to run my software:
For example, I have a need for Managed DirectX, so I look for some DLLs:
<Property Id="MANAGED_DIRECTX">
<DirectorySearch Path="$(env.SystemRoot)\Microsoft.NET\DirectX for Managed Code\1.0.2902.0" Depth="0" Id="MDXDir">
<FileSearch Name="Microsoft.DirectX.dll"/>
</DirectorySearch>
</Property>
<Property Id="MANAGED_DIRECTX_DIRECTINPUT">
<DirectorySearch Path="$(env.SystemRoot)\Microsoft.NET\DirectX for Managed Code\1.0.2902.0" Depth="0" Id="MDXInputDir">
<FileSearch Name="Microsoft.DirectX.DirectInput.dll"/>
</DirectorySearch>
</Property>
I also have a CustomAction to combine my condition logic:
<CustomAction Id="SetManagedDirectXInstalled"
Property="MANAGED_DIRECTX_INSTALLED"
Value="NOT([MANAGED_DIRECTX] = '') AND NOT ([MANAGED_DIRECTX_DIRECTINPUT] = ''")/>
This CustomAction is sequenced:
<InstallExecuteSequence>
<Custom Action="SetManagedDirectXInstalled" After="AppSearch" />
<RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>
What I should now be able to do is use "MANAGED DIRECTX INSTALLED" to do something, e.g.
<Control Id="NoManagedDirectX" Type="Text" X="20" Y="50" Width="300" Height="60" Transparent="yes" NoPrefix="yes" Hidden="yes">
<Text>Microsoft Managed DirectX (MDX) for DirectX 9.0 is NOT installed</Text>
<Condition Action="show">NOT MANAGED_DIRECTX_INSTALLED</Condition>
</Control>
<Control Id="ManagedDirectX" Type="Text" X="20" Y="50" Width="300" Height="60" Transparent="yes" NoPrefix="yes" Hidden="yes">
<Text>Microsoft Managed DirectX (MDX) for DirectX 9.0 is correctly installed</Text>
<Condition Action="show">MANAGED_DIRECTX_INSTALLED</Condition>
</Control>
It doesn't matter what I do, the condition is always false (e.g. not installed) even when I know the files are there. Using the msiexec command with /l*vx does not show the MANAGED DIRECTX INSTALLED property anywhere.
When a <Condition> is used with the following, it successfully prevents installation (although I no longer want to block installs in this case, just advise).
<Condition Message="You must have Microsoft Managed DirectX (MDX) for DirectX 9.0 installed">
MANAGED_DIRECTX AND MANAGED_DIRECTX_DIRECTINPUT
</Condition>
How can I trace/debug this (or what have I done wrong?)
EDIT - I'm now certain that my CustomAction is not even being called, setting it to the following is not showing expected results either!
<CustomAction Id='SetManagedDirectXInstalled'
Property='MANAGED_DIRECTX_INSTALLED'
Value='Something hard-coded'/>
or
<CustomAction Id='SetManagedDirectXInstalled'
Error='Some error should show!'/>
I think I may have found the answer, but I can't try it until I'm next at my development PC.
It appears I have to compare the values to TRUE/FALSE (or empty string) not just expecting it to work as boolean (Source)
In these expressions, you can use
property names (remember that they are
case sensitive). Non-existent property
names will be treated as empty
strings. The logical value of a
property reflects whether it has been
set—meaning that you cannot check for
a logical value by simply using the
property:
PROPERTY
This will evaluate to true if the property has been set and has any
value, even if this value is false.
NOT PROPERTY
This will evaluate to true if the property has not been set at all.
PROPERTY = TRUE
PROPERTY = FALSE
This is the proper way to check the value of a logical property.
To debug, use a verbose log file. It will show you the states of your Properties as they change. You should then be able to evaluate the Condition with that knowledge
I answered this same question not too long ago here. A Condition that uses the Property name is a test for existence. An existence test for a Property evaluates to true if the Property has any value at all. If you want to check the value of a Property you need to do so explicitly.