我正在尝试使用“值”属性创建自定义操作,我想将参数传递给C#代码(TARGETDIR和版本)。
但是,我收到一条错误消息,指出DLLENtry和Value无法共存。但是没有dllentry的自定义操作无效。
这是代码:
<CustomAction Id="SetMAWPrefferences"
Value="InstallDir=[TARGETDIR];Version=2.0.0.1"
Return="check"
Execute="commit"
BinaryKey="ImportExportBinary"
/>
为此,我收到此错误:
错误9 ICE68:动作'SetMAWPrefferences'的自定义动作类型无效。
任何想法怎么做?
注意,您以错误的方式使用Value
属性:
...此属性必须与Property属性一起使用以设置属性... [Source
基于Creating WiX Custom Actions in C# and Passing Parameters文章,您应该:
创建具有所需值的属性:
<Property Id="InstallDir" Value="someDefaultValue" />
<Property Id="Version" Value="2.0.0.1" />
创建自定义操作以设置InstallDir
属性:
<CustomAction Id="SetDirProp" Property="InstallDir" Value="[TARGETDIR]" />
创建自定义操作:
<CustomAction Id="SetMAWPrefferences"
Return="check"
Execute="commit"
BinaryKey="ImportExportBinary"
DllEntry="YourCustomAction" />
安排在安装过程中执行的自定义操作:
<InstallExecuteSequence>
<Custom Action="SetDirProp" After="CostFinalize" />
<Custom Action="SetMAWPreferences" ... />
...
</InstallExecuteSequence>
从您的自定义操作访问这些属性,如下所示:
[CustomAction]
public static ActionResult YourCustomAction(Session session)
{
// session["InstallDir"]
// session["Version"]
}
有两种将参数传递给自定义操作的方法,一种将用于立即执行CA,另一种将用于延迟的自定义操作。
立即CA(无法回滚):
为了将参数传递给直接CA,您可以设置具有所需名称的属性并从您的会话中访问它。
在蜡中:
<Property Id="MyProp" Value="MyValue" />
在CA中:
[CustomAction]
public static ActionResult NameOfMyCA(Session session)
{
string myArg = session["MyProp"];
}
延迟的CA:
为了将参数传递给延迟的CA,您需要使用CustomActionData Property,此属性是您可以从延迟的CA访问的唯一属性。
对于WIX,DTF包含一个CustomActionData类,它是一个键/值字典,您可以使用以下方法访问它:
在蜡中:
<CustomAction Id="MyCustomAction" .../>
<Property Id="MyCustomAction" Value="Arg1=value1;Arg2=value2;Arg3=value3;Arg4=[MyProperty]" />
在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"];
}
立即CA + CustomActionData:
如果您想将CustomActionData用于直接CA,则可以执行以下操作:
在蜡中:
<Property Id="MyCustomAction" Value="Arg1=value1;Arg2=value2;Arg3=value3;Arg4=[MyProperty]" />
在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"]);
}
对于Arg4,因为它包含属性的值,所以您需要像这样访问它:
string arg4 = session.Format(data["Arg4"]);
不幸的是,这仅在直接CA中有效,这意味着,如果要在延迟CA中使用此属性的值,则需要执行两个自定义操作:
CA 1设置为立即执行的CA的CustomActionData。 (请记住,使用与您的CustomAction相同的名称来命名属性。
CA 2具有使用CustomActionData的特定逻辑的CA。
我建议您在所有情况下都使用CustomActionData,这样可以更轻松地将CA从Instant转换为Deferred,并且代码也更易于阅读。
参考: