Как передать свойства msiexec в настраиваемое действие WiX C #? - PullRequest
27 голосов
/ 07 мая 2009

У меня есть файл MSI, созданный с помощью Wxs 3.0. Мой MSI ссылается на пользовательское действие C #, написанное с использованием нового проекта C # Custom Action .

Я хочу передать аргумент 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)
{

}

Я ожидал, что смогу получить доступ к свойству следующим образом:

string environmentName = session.Property ["ENVIRONMENT"];

но, похоже, это не работает.

Как получить доступ к свойству, которое я передал msiexec в моем настраиваемом действии?

Ответы [ 5 ]

30 голосов
/ 08 мая 2010

Если вместо

<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"];
14 голосов
/ 08 мая 2009

Просто для полноты; Использование метода, описанного Джереми Лью, в блоге выше позволяет следующее:

Призвание:

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 довольно уродлив, но он работает. Надеюсь, кто-нибудь знает более изящный способ сделать это.

8 голосов
/ 09 января 2012

Вот мой рабочий код:

<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"];
    ...
}
8 голосов
/ 07 мая 2009

Ваше пользовательское действие должно быть отложенным пользовательским действием для запуска после InstallFiles. Отложенные пользовательские действия не имеют доступа к свойствам, но они имеют доступ к CustomActionData. См. в этом блоге для обсуждения того, как узнать, что с этим делать. (Этот пример представляет собой настраиваемое действие VBScript, но вы сможете получить значение через коллекцию session.CustomActionData.)

0 голосов
/ 30 августа 2016

Если мы говорим о Wix Sharp (а не о простом Wix с его XML-компонентами), добавление пользовательского свойства - это просто. Все, что вам нужно сделать, это установить 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;
}

Если свойство не установлено в командной строке, значением по умолчанию будет пустая строка.

...