I\'m trying to create a custom action with \"Value\" attribute, I want to pass parameters to the C# code (the TARGETDIR and the version).
However, I get an error sta
Note, you're using Value
attribute in the wrong way:
...this attribute must be used with the Property attribute to set the property...Source
Based on the Creating WiX Custom Actions in C# and Passing Parameters article you should:
Create properties with desired values:
<Property Id="InstallDir" Value="someDefaultValue" />
<Property Id="Version" Value="2.0.0.1" />
Create custom action to set the InstallDir
property:
<CustomAction Id="SetDirProp" Property="InstallDir" Value="[TARGETDIR]" />
Create custom action:
<CustomAction Id="SetMAWPrefferences"
Return="check"
Execute="commit"
BinaryKey="ImportExportBinary"
DllEntry="YourCustomAction" />
Schedule custom actions for execution during installation process:
<InstallExecuteSequence>
<Custom Action="SetDirProp" After="CostFinalize" />
<Custom Action="SetMAWPreferences" ... />
...
</InstallExecuteSequence>
Access those properties from your custom action as follows:
[CustomAction]
public static ActionResult YourCustomAction(Session session)
{
// session["InstallDir"]
// session["Version"]
}
There are two ways to pass parameters to the custom actions, one will work for the immediate execution CA and the other one will work for the deferred custom actions.
Immediate CA (Can't be rolled back):
In order to pass arguments to the immediate CA you can set a property with the required name and access it from your session.
In Wix:
<Property Id="MyProp" Value="MyValue" />
In CA:
[CustomAction]
public static ActionResult NameOfMyCA(Session session)
{
string myArg = session["MyProp"];
}
Deferred CA:
In order to pass arguments to the deferred CA you need to use the CustomActionData Property, this property is the only one you can access from a deferred CA.
In the case of WIX, the DTF includes a CustomActionData class which is a key/value dictionary, and you can access it using:
In Wix:
<CustomAction Id="MyCustomAction" .../>
<Property Id="MyCustomAction" Value="Arg1=value1;Arg2=value2;Arg3=value3;Arg4=[MyProperty]" />
In CA:
[CustomAction]
public static ActionResult NameOfMyCA(Session session)
{
CustomActionData data = session.CustomActionData;
//Access each argument like this:
string arg1 = data["Arg1"];
string arg2 = data["Arg2"];
string arg3 = data["Arg3"];
}
Immediate CA + CustomActionData:
If you want to use the CustomActionData for your Immediate CA you can do something like this:
In Wix:
<Property Id="MyCustomAction" Value="Arg1=value1;Arg2=value2;Arg3=value3;Arg4=[MyProperty]" />
In CA:
[CustomAction]
public static ActionResult NameOfMyCA(Session session)
{
CustomActionData data = new CustomActionData(session["MyCustomAction"]);
//Access each argument like this:
string arg1 = data["Arg1"];
string arg2 = data["Arg2"];
string arg3 = data["Arg3"];
string arg4 = session.Format(data["Arg4"]);
}
In the case of Arg4 since it contains the value of a property you will need to access it like this:
string arg4 = session.Format(data["Arg4"]);
Unfortunately this will work in immediate CA only, this means that if you want to use the value of this property in a deferred CA you will need to have two custom actions:
CA 1 to set the CustomActionData for the CA executed as immediate. (Remember to name the property with the same name defined for your CustomAction.
CA 2 the CA with the specific logic that consumes CustomActionData.
I suggest you to use the CustomActionData for all the cases, this way is easier to convert you CA from Immediate to Deferred and the code is easier to read.
References:
session.Format CustomActionData