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

17

我试图创建一个带有“Value”属性的自定义操作,我想将参数传递给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',自定义操作类型无效。

您有任何解决方法吗?

2个回答

44

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

立即CA(无法撤消):

为了向立即CA传递参数,您可以设置具有所需名称的属性并从会话中访问它。

在Wix中:

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

在加州:

[CustomAction]
public static ActionResult NameOfMyCA(Session session)
{
    string myArg = session["MyProp"];
}   

延迟自定义操作:

为了将参数传递给延迟自定义操作,您需要使用CustomActionData Property,这是您可以从延迟自定义操作中访问的唯一属性。

在WIX的情况下,DTF包括一个CustomActionData类,它是一个键/值字典,您可以使用以下方式访问它:

在Wix中:

<CustomAction Id="MyCustomAction" .../>

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

在加利福尼亚州:

[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:

如果您想在立即 CA 中使用 CustomActionData,可以尝试以下方法:

在 Wix 中:

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

在加州:

[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。(记得使用与自定义操作定义的相同名称命名属性。)

  • CA 2:具有消耗 CustomActionData 的特定逻辑的 CA。

建议您对所有情况都使用 CustomActionData,这样更容易将 CA 从即时转换为延迟,并且代码更易于阅读。

参考资料:

session.Format CustomActionData


1
我认为这个答案缺少实际设置属性的<custom action>,例如 <CustomAction Id="SetDirProp" Property="InstallDir" Value="[TARGETDIR]" /> - Steve Smith

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

......必须将此属性与 Property 属性一起使用来设置该属性......来源


根据创建 C# WiX 自定义操作并传递参数文章的描述,你应该这样做:
  1. Create properties with desired values:

    <Property Id="InstallDir" Value="someDefaultValue" />
    <Property Id="Version" Value="2.0.0.1" />
    
  2. Create custom action to set the InstallDir property:

    <CustomAction Id="SetDirProp" Property="InstallDir" Value="[TARGETDIR]" />
    
  3. Create custom action:

    <CustomAction Id="SetMAWPrefferences" 
        Return="check" 
        Execute="commit" 
        BinaryKey="ImportExportBinary" 
        DllEntry="YourCustomAction" />
    
  4. Schedule custom actions for execution during installation process:

    <InstallExecuteSequence>
        <Custom Action="SetDirProp" After="CostFinalize" />
        <Custom Action="SetMAWPreferences" ... />
        ...
    </InstallExecuteSequence>
    
  5. Access those properties from your custom action as follows:

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

嗨,值没有传递 - 我得到了 null。 - Ehud Grand
@user1223457,我又更新了答案,希望能有所帮助。 - Yurii
不,我仍然只得到一个字符串“TARGETDIR”。 - Ehud Grand
@user1223457,请尝试在<CustomAction Id="SetDirProp"中将Value="[TARGETDIR]"更改为Value="[INSTALLFOLDER]" - Yurii
1
Execute="commit"...........不行。只有在启用回滚时,Commit CA 才会在 InstallFinalize 之后执行。如果您正在设置属性,则需要在 immediate CA 中完成;如果您正在更改目标系统,则需要在 deferred CA 中完成。Commit CA 用于在成功安装后清理临时文件。 - Izzy
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接