27

我有一个使用 Wxs 3.0 创建的 MSI 文件。我的 MSI 引用了一个 C# 自定义操作,它是使用新的C# Custom Action project编写的。

我想将一个参数传递给 msiexec,该参数被路由到我的自定义操作 - 例如:

msiexec /i MyApp.msi ENVIRONMENT=TEST#

在我的 .wxs 文件中,我指的是这样的自定义操作:

<Property Id="ENVIRONMENT"/>
<Binary Id="WixCustomAction.dll"  SourceFile="$(var.WixCustomAction.Path)" />
<CustomAction Id="WixCustomAction" BinaryKey="WixCustomAction.dll"    DllEntry="ConfigureSettings"/>
<InstallExecuteSequence>
   <Custom Action="WixCustomAction" After="InstallFiles"></Custom>
</InstallExecuteSequence>

我的 C# 自定义操作设置如下:

[CustomAction]
public static ActionResult ConfigureSettings(Session session)
{

}

我期望能够像这样访问该属性:

字符串 environmentName = session.Property["ENVIRONMENT"];

但这似乎不起作用。

如何访问我在自定义操作中传递给 msiexec 的属性?

4

5 回答 5

30

如果不是

<CustomAction Id="SetCustomActionDataValue"
              Return="check"
              Property="Itp.Configurator.WixCustomAction"
              Value="[ENVIRONMENT],G2,[CONFIGFILE],[TARGETDIR]ITP_v$(var.VERSION_MAJOR)" />

你写这个:

<CustomAction Id="SetCustomActionDataValue"
              Return="check"
              Property="Itp.Configurator.WixCustomAction"
              Value="Environment=[ENVIRONMENT];G=G2;ConfigFile=[CONFIGFILE];TargetDir=[TARGETDIR]ITP_v$(var.VERSION_MAJOR)" />

那么您将能够像这样引用您的变量:

string env=session.CustomActionData["Environment"];
于 2010-05-08T19:06:52.007 回答
14

只是为了完整性;使用 Jeremy Lew 描述的方法,在上面的博客中允许以下内容:

来电:

msiexec /i ITP.Platform.2.msi ENVIRONMENT=QA CONFIGFILE=EnvironmentConfig.xml

在 .wxs 文件中使用这个:

<Property Id="ENVIRONMENT" Secure="yes" />
<Property Id="CONFIGFILE" Secure="yes" />
<Binary Id="Itp.Configurator.WixCustomAction.dll"
        SourceFile="$(var.Itp.Configurator.WixCustomAction.Path)" />

<CustomAction Id="SetCustomActionDataValue"
              Return="check"
              Property="Itp.Configurator.WixCustomAction"
              Value="[ENVIRONMENT],G2,[CONFIGFILE],[TARGETDIR]ITP_v$(var.VERSION_MAJOR)" />

<CustomAction Id="Itp.Configurator.WixCustomAction"
              Return="check"
              Execute="deferred"
              BinaryKey="Itp.Configurator.WixCustomAction.dll"
              DllEntry="ConfigureItpBrandSettings" />

<InstallExecuteSequence>
  <Custom Action="SetCustomActionDataValue" After="InstallFiles"></Custom>
  <Custom Action="Itp.Configurator.WixCustomAction" After="SetCustomActionDataValue"></Custom>
</InstallExecuteSequence>

使用自定义操作:

    /// <summary>
    /// CustomAction keys should be Environment,BrandId,ConfigPath,itpBasePath
    /// </summary>
    /// <param name="session"></param>
    /// <returns></returns>
    [CustomAction]
    public static ActionResult ConfigureItpBrandSettings(Session session)
    {
        string[] arguments = GetCustomActionDataArguments(session);

        string environmentName = arguments[0];
        string brandId = arguments[1];
        string configPath = arguments[2];
        string itpBasePath = arguments[3];

        //Do stuff

        return ActionResult.Success;
    }

    private static string[] GetCustomActionDataArguments(Session session)
    {
        string[] keys = new string[session.CustomActionData.Keys.Count];
        session.CustomActionData.Keys.CopyTo(keys,0);
        return keys[0].Split(',');
    }

作品。

解析 CustomActionData 参数非常难看,但它确实有效。希望有人知道一种更优雅的方式来做到这一点。

于 2009-05-08T16:19:30.440 回答
8

您的自定义操作需要是延迟自定义操作才能在 InstallFiles 之后运行。延迟的自定义操作无法访问属性,但它们可以访问 CustomActionData。有关如何处理它的讨论,请参阅此博客文章。(此示例是一个 VBScript 自定义操作,但您将能够通过 session.CustomActionData 集合检索该值。)

于 2009-05-07T16:39:39.427 回答
8

这是我的工作代码:

<Binary Id="MyCA" SourceFile="..\bin\ChainerRun.CA.exe" />

<CustomAction Id="SetCustomActionDataValue" Return="check" Property="CustomActionData" Value="TARGETDIR=[TARGETDIR];AA=Description;" />

<CustomAction Id="ReadAndSet" 
            BinaryKey="MyCA" 
            DllEntry="ReadAndSet" 
            Execute="immediate"
            HideTarget="no" 
            Return="check" />

<InstallExecuteSequence>
    <Custom Action="SetCustomActionDataValue" Before="InstallFiles" />
    <Custom Action="ReadAndSet" After="SetCustomActionDataValue" />
</InstallExecuteSequence>

在 C# 自定义操作函数中:

[CustomAction]
public static ActionResult ReadAndSet(Session session)
{
    ActionResult retCode = ActionResult.NotExecuted;

    System.Diagnostics.Debug.Assert(false);

    session.Log("ReadAndSet() begins ...");

    string installLocation = session.CustomActionData["TARGETDIR"];
    string hostName = session.CustomActionData["AA"];
    ...
}
于 2012-01-09T17:22:47.780 回答
0

如果我们谈论的是 Wix Sharp(而不是带有 XML 内容的普通 Wix),那么添加自定义属性就是小菜一碟。您所要做的就是为您的托管操作设置UsesProperties属性。

例如,如果您想添加一个名为“ MYPROP ”的自定义属性,只需像这样定义您的操作:

new ElevatedManagedAction(nameof(CustomActions.MyCustomAction))
{
    Condition = Condition.Installed,
    When = When.Before,
    Step = Step.RemoveFiles,
    Return = Return.check,
    Execute = Execute.deferred,
    UsesProperties = "MYPROP"
}

通过 msiexec 命令行设置属性值:

msiexec /i my.msi MYPROP=MYVALUE

然后您将能够从您的自定义操作中访问它:

[CustomAction]
public static ActionResult MyCustomAction(Session session)
{
    session.Log("MYPROP VALUE: " + session.CustomActionData["MYPROP"]);
    return ActionResult.Success;
}

当属性未通过命令行设置时,默认值为空字符串。

于 2016-08-30T09:22:35.013 回答