关于c#:如何将参数传递给自定义操作?

How to pass parameters to the custom action?

我正在尝试创建一个具有" Value"属性的自定义操作,我想将参数传递给C#代码(TARGETDIR和版本)。

但是,我收到一条错误消息,指出DLLENtry和Value无法共存。但是没有dllentry的自定义操作无效。

这是代码:

1
2
3
4
5
6
 <CustomAction Id="SetMAWPrefferences"
                Value="InstallDir=[TARGETDIR];Version=2.0.0.1"
                Return="check"
                Execute="commit"
                BinaryKey="ImportExportBinary"                    
                />

为此,我收到此错误:

Error 9 ICE68: Invalid custom action type for action 'SetMAWPrefferences'.

有什么想法怎么做?


有两种方法可以将参数传递给自定义操作,一种方法用于立即执行CA,另一种方法用于延迟的自定义操作。

立即CA(无法回滚):

为了将参数传递给直接CA,您可以设置具有所需名称的属性,然后从您的会话中访问它。

在蜡中:

1
<Property Id="MyProp" Value="MyValue" />

在CA中:

1
2
3
4
5
[CustomAction]
public static ActionResult NameOfMyCA(Session session)
{
    string myArg = session["MyProp"];
}

延迟的CA:

为了将参数传递给延迟的CA,您需要使用CustomActionData属性,此属性是您可以从延迟的CA访问的唯一属性。

对于WIX,DTF包含一个CustomActionData类,它是一个键/值字典,您可以使用以下方法访问它:

在蜡中:

1
2
3
<CustomAction Id="MyCustomAction" .../>

<Property Id="MyCustomAction" Value="Arg1=value1;Arg2=value2;Arg3=value3;Arg4=[MyProperty]" />

在CA中:

1
2
3
4
5
6
7
8
9
10
11
[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,则可以执行以下操作:

在蜡中:

1
<Property Id="MyCustomAction" Value="Arg1=value1;Arg2=value2;Arg3=value3;Arg4=[MyProperty]" />

在CA中:

1
2
3
4
5
6
7
8
9
10
11
12
[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,由于它包含属性的值,因此您需要像这样访问它:

1
string arg4 = session.Format(data["Arg4"]);

不幸的是,这仅在直接CA中有效,这意味着,如果要在延迟CA中使用此属性的值,则需要执行两个自定义操作:

  • CA 1设置立即执行的CA的CustomActionData。 (请记住要使用为您的CustomAction定义的相同名称来命名属性。

  • CA 2具有使用CustomActionData的特定逻辑的CA。

我建议您在所有情况下都使用CustomActionData,这样可以更轻松地将CA从"立即"转换为"延迟",并且代码也更易于阅读。

参考文献:

session.Format
CustomActionData


请注意,您以错误的方式使用了Value属性:

...this attribute must be used with the Property attribute to set the property...Source

基于在C#中创建WiX自定义操作和传递参数一文,您应该:

  • 创建具有所需值的属性:

    1
    2
    <Property Id="InstallDir" Value="someDefaultValue" />
    <Property Id="Version" Value="2.0.0.1" />
  • 创建自定义操作以设置InstallDir属性:

    1
    <CustomAction Id="SetDirProp" Property="InstallDir" Value="[TARGETDIR]" />
  • 创建自定义动作:

    1
    2
    3
    4
    5
    <CustomAction Id="SetMAWPrefferences"
        Return="check"
        Execute="commit"
        BinaryKey="ImportExportBinary"
        DllEntry="YourCustomAction" />
  • 计划在安装过程中执行的自定义操作:

    1
    2
    3
    4
    5
    <InstallExecuteSequence>
        <Custom Action="SetDirProp" After="CostFinalize" />
        <Custom Action="SetMAWPreferences" ... />
        ...
    </InstallExecuteSequence>
  • 通过以下自定义操作访问这些属性:

    1
    2
    3
    4
    5
    6
    [CustomAction]
    public static ActionResult YourCustomAction(Session session)
    {
        // session["InstallDir"]
        // session["Version"]
    }