WiX:如何访问/更改托管引导程序中的安装目录?

时间:2013-02-22 07:37:53

标签: c# wix bootstrapper

我正在使用自定义用户界面创建WPF设置应用程序。我从Bryan P. Johnston的教程开始:http://bryanpjohnston.com/2012/09/28/custom-wix-managed-bootstrapper-application/

在我看来,我有一个简单的TextBox绑定到InstallationPath中的一个属性MainViewModel

现在我希望在用户点击“安装”时使用此路径。为此,我有一个绑定到InstallCommand的按钮。调用以下方法(直接从教程中获取):

private void InstallExecute()
{
    Bootstrapper.Engine.Plan(LaunchAction.Install);
}

如何将软件包安装到我的属性InstallationPath的目录中?


编辑:

我在Stackoverflow上发现了一个类似的问题:

Specify the INSTALLLOCATION of packages in WiX inside the Burn managed bootstrapper

答案来自Bob Arnson

  

为每个MsiPackage使用MsiProperty子项指定INSTALLLOCATION = [BurnVariable]。然后使用Engine.StringVariables设置BurnVariable。

现在,我想我可以像我这样StringVariables访问InstallExecute

private void InstallExecute()
{
    Bootstrapper.Engine.StringVariables["BurnVariable"] = InstallationPath;
    Bootstrapper.Engine.Plan(LaunchAction.Install);
}

但是在哪里定义这个变量?我想在Product.wxs的哪个地方?

3 个答案:

答案 0 :(得分:7)

是的,只需在刻录引导程序中创建一个变量:

<Variable Name="BurnVariable"
          bal:Overridable="yes" />

然后,您可以将此参数作为参数传递给引导程序的msi程序包:

<MsiPackage SourceFile="$(var.YourMsiProject.Installer.TargetPath)" Compressed="no">
    <MsiProperty Name="INSTALLLOCATION" Value="[BurnVariable]" />          
</MsiPackage>

答案 1 :(得分:1)

一个遗失的财产&#34; Type&#34;在Bundle Variable元素上。 caverman_dick是正确的但是当不可覆盖时这不能正常工作。 您也可以尝试这一点,设置Type =&#34; string&#34;。

Wix Variable Element

<Wix>...<Bundle>...
  <Variable Name="MyApplicationMsiInstallFolder" Value="[WindowsVolume]MyApplication"
          bal:Overridable="yes" Type="string"/>
    <Chain>
        <?if $(var.DbVersion) = false?>
        <PackageGroupRef Id="AccessDatabaseGroup"/>
        <RollbackBoundary />
        <?endif?>
        <MsiPackage Id="MyApplicationMsiPackage" SourceFile="$(var.MyApplicationSetup.TargetPath)" DisplayInternalUI="no"
                                Vital="yes" >
            <MsiProperty Name="APPLICATIONFOLDER" Value="[MyApplicationMsiInstallFolder]"/>
        </MsiPackage>
    </Chain>
</Bundle></Wix>

答案 2 :(得分:0)

我也使用这个传奇教程。我想将veriable用于其他用途。即,该变量说明是否应安装该程序。问题在于,在InstallExecute()中调用该变量时不会覆盖该变量。对于我的问题,它是以这种方式工作的:

  protected override void Run()
    {
        this.Engine.Log(LogLevel.Verbose, "Launching custom TestBA UX");
        BootstrapperDispatcher = Dispatcher.CurrentDispatcher;


        MainViewModel viewModel = new MainViewModel(this);
        viewModel.Bootstrapper.Engine.Detect();

        MainView view = new MainView();
        this.Engine.StringVariables["SqlStatus"] = view.CheckInstalledSQL() == true ? "true" : "false";
        this.Engine.StringVariables["SsmsStatus"] = view.CheckInstalledSSMS() == true ? "true" : "false";
        view.DataContext = viewModel;
        view.Closed += (sender, e) => BootstrapperDispatcher.InvokeShutdown();
        view.Show();
        Dispatcher.Run();

        this.Engine.Quit(0);
    }

引导程序:

<Variable Name="SqlStatus" bal:Overridable="yes" Value="false" Type="string"/>
<Variable Name="SsmsStatus" bal:Overridable="yes" Value="false" Type="string"/>
...

<ExePackage Id="SSMS" Name="SQLServerManagementStudio" Cache="no" Compressed="yes" PerMachine="yes" Permanent="yes" Vital="yes"
    InstallCommand="/install /Passive SSMSInstallRoot=C:\\Program Files\\Microsoft SQL Server /norestart"
    SourceFile="C:\Users\..\Downloads\SSMS-Setup-ENU.exe"
    DetectCondition="SsmsStatus = &quot;true&quot;"/>