WiX customaction doesnot have value for session.Property["CustomActionData"] - wix

I have to pass a value to my custom action in patch release for my feature. I did some research and did the following:
<CustomAction Id="CustomAction1" Property="customaction2" Value="Value1" />
<CustomAction Id="customaction2" BinaryKey="Binary.dll"
DllEntry="Functionname" Impersonate="no"
Execute="immediate" Return="check" />
I also updated the installExecuteSequence as below:
<Custom Action='CustomAction1' After="InstallFinalize"><![CDATA[PATCH]]></Custom>
<Custom Action='customaction2' After="CustomAction1"><![CDATA[PATCH]]></Custom>
I also added the componentrefs to the patch.wxs file.
<CustomActionRef Id="CustomAction1.PackageGuid"/>
<CustomActionRef Id="customaction2.PackageGuid"/>
To access this parameter value, I tried the following code in my customaction "Functionname" :
var value = session.Property["CustomActionData"];
The "value" is Empty. I did some debugging and found that, i am getting the value from below code:
var value = session.Property["customaction2.PackageGuid"];
I have not seen any examples that access properties with packageGuids also. I am not sure why the first approach(using "CustomActionData") is not working for me.
Can you guys let me know what i am missing?
Also, Is there any harm in using with packageGuids? If not, i am planning to continue this way. Please let me know if you need me to try any other st

Related

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 to define a CustomAction with a long command line in WIX?

I have define a custom action in my wxs file:
<CustomAction ExeCommand="long command line" FileKey="xyz.exe" Id="foo"/>
and I receive the warning:
warning LGHT1076 : ICE03: String overflow (greater than length
permitted in column); Table: CustomAction, Column: Target, Key(s):
What is the right solution to define an action with a long command line?
After many time I have find a solution. I split the command line into multiple properties.
<CustomAction Id="action.prop0" Property="prop0" Value="first part with [INSTALLDIR]"/>
<CustomAction Id="action.prop" Property="prop" Value="[prop0] second part"/>
<CustomAction ExeCommand="[prop]" FileKey="service.exe" Id="myaction"/>
<InstallExecuteSequence>
<Custom Action="action.prop0" After="InstallFiles"/>
<Custom Action="action.prop" After="action.prop0"/>
<Custom Action="myaction" Before="InstallFinalize"/>
</InstallExecuteSequence>
Assign the long command line to a property and then use [PROPERTY] in the custom action. Although EXE custom actions in general are frowned upon. If you must do it use the WiX Quiet Execute Custom Action feature.

WiX - commit more than one Property to deferred Custom Action

I have a problem with my WiX installer in contact with deferred / immediate custom actions. Please excuse my english.
I want to surrender some properties, entered by the user, to a deferred custom action. I know that I need a immediate custom action and "CustomActionData" to do that. I´ve implement it at this way.
The binary:
<Binary Id='myAction' SourceFile='.\TemplateGeneration.CA.dll'/>
The immediate custom action:
<CustomAction Id='Datenuebergabe' Property='DoSomething' Value='InstalllocVar=[INSTALLLOCATION]'/>
The deferred custom action:
<CustomAction Id='TemplateGenerationInstallKey' BinaryKey ='myAction' DllEntry='DoSomething' Impersonate='no' Execute='deferred' Return='check' HideTarget='yes'/>
The InstallExecuteSequence
<InstallExecuteSequence>
<Custom Action="Datenuebergabe" Sequence="1399"/>
<Custom Action="TemplateGenerationInstallKey" Before="InstallFinalize"/>
</InstallExecuteSequence>
Calling the property in the deferred custom action:
string somedata = session.CustomActionData["InstalllocVar"];
TemplateEngineCall(somedata+"templates", "install_key_cmd", somedata+"scripts", "install_key.cmd");
My problems:
If I try to install my program it breaks.
With this code i only can surrender one property, but I need to commit more than one.
For information:
When I have a look at the log file, there´s a System.Collections.Generic.KeyNotFoundException while the custom action call.
Why doesn´t this work?
Well, I need the deferred custom action to write into the "program files folder". Because of the needed rights, the deferred custom action is required and the immediate custom action executed before the deferred should help to handle the properties. Is it possible to do that?
I hope you understand what are my problems and possible you can try to help me.
First of all, there's a mistake in the way you pass the data from immediate custom action to the deferred one. The name of the Property you use in the immediate custom action must be exactly the same as the Id of the deferred custom action. In your case:
<!-- immediate CA -->
<CustomAction Id='Datenuebergabe' Property='DoSomething' Value='InstalllocVar=[INSTALLLOCATION]'/>
<!-- deferred CA -->
<CustomAction Id='DoSomething' BinaryKey ='myAction' DllEntry='DoSomething' Impersonate='no' Execute='deferred' Return='check' HideTarget='yes'/>
This will resolve the problem with KeyNotFound exception.
Now, back to your question how to pass more than 1 value.
First, in the immediate CA use ; separator to pass the name-value collection, like this:
<CustomAction Id="SetForDoSomething" Return="check" Property="DoSomething" Value="source=[ArchiveFolder][ARCHIVENAME];target=[WebsiteFolder]"/>
As you can see, there are 2 name-value pairs we pass to the deferred CA here, source and target. In the deferred CA, use the following code to take those values out:
var source = session.CustomActionData["source"];
var target = session.CustomActionData["target"];
And that's it.

Set property value based on condition in WiX

I searched through several questions at Stack Overflow, but nothing helped me. The problem is:
I look in the registry for some value (I know how to do that). I know how to set property. But I cannot find the way how to write this expression in WiX. This is what I want to write in pseudocode:
if(registryvalue contains substring1)
set property to value1
if(registryvalue contains substring2)
set property to value2
This condition must be evaluated at runtime. Is there a way to write this condition? What would some sample code look like?
You can use a type 51 custom action to set the property:
<CustomAction Id="SET_VALUE1" Property="TEST_PROPERTY" Value="value1" />
<CustomAction Id="SET_VALUE2" Property="TEST_PROPERTY" Value="value2" />
Use the condition when you call the custom action in install sequences:
<Custom Action="SET_VALUE1" After="AppSearch">Not Installed AND (REG_VALUE="substring1")</Custom>
<Custom Action="SET_VALUE2" After="AppSearch">Not Installed AND (REG_VALUE="substring2")</Custom>
Or you can write the custom actions in managed code like C#, and schedule it after AppSearch in case you have many comparisons.

Execute a custom action before Product condition

Basically I need to verify that a certain program is not running before installation. This is done via a custom action, which sets a property, APPRUNNING:
<CustomAction Id="CheckingAppIsRunning"
BinaryKey="AppIsRunning"
DllEntry="AppIsRunning"/>
<Binary Id="AppIsRunning"
SourceFile="CustomActions.CA.dll" />
But in the message displayed, APPRUNNING seems to be null, that is, it's not set at all (should be either "0" or "1").
<Condition Message="Exit all instances of [APPNAME] before installation (APPRUNNING = [APPRUNNING]).">
<![CDATA[APPRUNNING = "0"]]>
</Condition>
<InstallExecuteSequence>
<Custom Action="CheckingAppIsRunning" Before="LaunchConditions" />
</InstallExecuteSequence>
I suppose the custom action is not executed at the moment of the condition check. What are the options to perform a condition check after a custom action?
The LaunchConditions action is scheduled to run in both InstallUISequence and InstallExecuteSequence. As long as you schedule your custom action to InstallExecuteSequence only, the property won't be set by the time LaunchConditions is fired in InstallUISequence.
You should schedule your CheckingAppIsRunning custom action in both sequences. You might also want to define it with Execute='firstSequence' attribute - this way it will run the first sequence it is met in.
This is what I mean, actually:
<InstallUISequence>
<Custom Action="CheckingAppIsRunning" Before="LaunchConditions" />
</InstallUISequence>
<InstallExecuteSequence>
<Custom Action="CheckingAppIsRunning" Before="LaunchConditions" />
</InstallExecuteSequence>
And the definition:
<CustomAction Id="CheckingAppIsRunning" BinaryKey="AppIsRunning" DllEntry="AppIsRunning" Execute="firstSequence"/>