如何将参数传递给自定义操作?

问题描述 投票:11回答:2

我正在尝试使用“值”属性创建自定义操作,我想将参数传递给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'的自定义动作类型无效。

任何想法怎么做?

c# wix custom-action
2个回答
7
投票

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

...此属性必须与Property属性一起使用以设置属性... [Source


基于Creating WiX Custom Actions in C# and Passing Parameters文章,您应该:

  1. 创建具有所需值的属性:

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

    <CustomAction Id="SetDirProp" Property="InstallDir" Value="[TARGETDIR]" />
    
  3. 创建自定义操作:

    <CustomAction Id="SetMAWPrefferences" 
        Return="check" 
        Execute="commit" 
        BinaryKey="ImportExportBinary" 
        DllEntry="YourCustomAction" />
    
  4. 安排在安装过程中执行的自定义操作:

    <InstallExecuteSequence>
        <Custom Action="SetDirProp" After="CostFinalize" />
        <Custom Action="SetMAWPreferences" ... />
        ...
    </InstallExecuteSequence>
    
  5. 从您的自定义操作访问这些属性,如下所示:

    [CustomAction]
    public static ActionResult YourCustomAction(Session session)
    {
        // session["InstallDir"]
        // session["Version"]
    }
    

30
投票

有两种将参数传递给自定义操作的方法,一种将用于立即执行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,并且代码也更易于阅读。

参考:

session.FormatCustomActionData

© www.soinside.com 2019 - 2024. All rights reserved.