Como faço para passar as propriedades msiexec a uma ação # costume WiX C?
-
08-07-2019 - |
Pergunta
Eu tenho um arquivo MSI que está sendo criado com WXS 3.0. Meu MSI faz referência a um C acção # costume, escrito usando o novo C # personalizado projeto Ação .
Eu quero passar um argumento para msiexec que será encaminhado à minha ação personalizada - por exemplo:
msiexec / i MyApp.msi AMBIENTE = TEST #
Na minha .wxs arquivo, refiro-me à minha ação personalizada como esta:
<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>
Meu C acção # personalizado é configurado como este:
[CustomAction]
public static ActionResult ConfigureSettings(Session session)
{
}
Eu estava esperando para ser capaz de acessar a propriedade como esta:
string environmentName = session.Property [ "ambiente"];
mas isso não parece trabalho.
Como faço para acessar a propriedade I passado para msiexec na minha ação personalizada?
Solução
Se em vez de
<CustomAction Id="SetCustomActionDataValue"
Return="check"
Property="Itp.Configurator.WixCustomAction"
Value="[ENVIRONMENT],G2,[CONFIGFILE],[TARGETDIR]ITP_v$(var.VERSION_MAJOR)" />
você escreve o seguinte:
<CustomAction Id="SetCustomActionDataValue"
Return="check"
Property="Itp.Configurator.WixCustomAction"
Value="Environment=[ENVIRONMENT];G=G2;ConfigFile=[CONFIGFILE];TargetDir=[TARGETDIR]ITP_v$(var.VERSION_MAJOR)" />
então você será capaz de referenciar suas variáveis ??como esta:
string env=session.CustomActionData["Environment"];
Outras dicas
Apenas para a integralidade; usando o método descrito por Jeremy Lew, no blog acima permite o seguinte:
Chamar:
msiexec /i ITP.Platform.2.msi ENVIRONMENT=QA CONFIGFILE=EnvironmentConfig.xml
Com esta no arquivo .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>
Com uma ação personalizada:
/// <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(',');
}
obras.
Analisando os argumentos CustomActionData é muito feio, mas ela não funciona. Esperemos que alguém sabe uma maneira mais elegante de fazer isso.
Aqui está o meu código de trabalho:
<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>
Na função C # ação personalizada:
[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"];
...
}
As suas necessidades de ação personalizada para ser uma ação personalizada diferida, a fim de correr atrás InstallFiles. ações personalizadas diferidos não têm acesso a propriedades, mas eles têm acesso a CustomActionData. Veja este post para uma discussão sobre como conseguir o que fazer sobre isso. (Este exemplo é uma ação personalizada VBScript, mas você será capaz de recuperar o valor através da recolha session.CustomActionData.)
Se nós estamos falando sobre Wix Sharp (e não simples Wix com seu material XML), adicionando uma propriedade personalizada é um pedaço de bolo. Tudo que você tem a fazer é set UsesProperties propriedade para sua ação gerenciado.
Por exemplo, se você deseja adicionar uma propriedade personalizada com o nome " MyProp ", apenas definir a sua ação como esta:
new ElevatedManagedAction(nameof(CustomActions.MyCustomAction))
{
Condition = Condition.Installed,
When = When.Before,
Step = Step.RemoveFiles,
Return = Return.check,
Execute = Execute.deferred,
UsesProperties = "MYPROP"
}
Definir o valor da propriedade via linha de comando msiexec:
msiexec /i my.msi MYPROP=MYVALUE
E então você vai ser capaz de acessá-lo a partir de sua ação personalizada:
[CustomAction]
public static ActionResult MyCustomAction(Session session)
{
session.Log("MYPROP VALUE: " + session.CustomActionData["MYPROP"]);
return ActionResult.Success;
}
Quando a propriedade não está definida via linha de comando o valor padrão será uma cadeia vazia.