5

I am creating a WPF setup application with a custom user interface. I started with the tutorial of Bryan P. Johnston: http://bryanpjohnston.com/2012/09/28/custom-wix-managed-bootstrapper-application/

Somewhere in my view, I have a simple TextBox that binds to a Property InstallationPath in my MainViewModel.

Now I want this path to be used when the user clicks on "Install". For this, I have a button that binds to my InstallCommand. The following method is called (taken directly from the tutorial):

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

How can I make the packages to be installed into the directory of my property InstallationPath?


Edit:

I found a similar question here on Stackoverflow:

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

The answer there is from Bob Arnson

Use an MsiProperty child for each MsiPackage to specify INSTALLLOCATION=[BurnVariable]. Then use Engine.StringVariables to set BurnVariable.

Now, I think I could access the StringVariables in my InstallExecute like this

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

But where to define this variable? I guess somewhere in Product.wxs?

Community
  • 1
  • 1
Michael Hilus
  • 1,647
  • 2
  • 21
  • 42
  • Hey Michael, i followed this same tutorial and I'm facing an issue where during major upgrade, the previous exe is not getting removed as new one is installed side by side. I incremented both the EXE version and the included MSIs versions. I saw some other people commenting the same issue below the tutorial. Did you run into this issue? If so how did you get over it? :( Need some help man – AnOldSoul Apr 27 '16 at 02:31
  • I also use this legendary tutorial, the problem is that the variable does not overwrite. My variable returns information whether to install the program or not. I can read this veriable in program c# but cant overwrite, it doesn't matter when and when I do it, it doesn't change. Bootstrapper.Engine.StringVariables["SqlStatus"] = "false"; Maybe someone can help me. – Silny ToJa May 12 '20 at 10:45

3 Answers3

7

Yes just create a variable in your burn bootstrapper:

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

you can then pass this as a parameter to your boot-strapped msi package:

<MsiPackage SourceFile="$(var.YourMsiProject.Installer.TargetPath)" Compressed="no">
    <MsiProperty Name="INSTALLLOCATION" Value="[BurnVariable]" />          
</MsiPackage>
caveman_dick
  • 6,302
  • 3
  • 34
  • 49
1

One missing property "Type" on Bundle Variable element. caverman_dick is right but this not works properly when not overridable. You can try this too, setting Type="string".

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>
antonio
  • 548
  • 8
  • 16
0

I also use this legendary tutorial. I wanted to use veriable for something else. Namely, the variable says whether the program should be installed. The problem is that the variable does not overwrite when invoke it in InstallExecute(). For my problem it work in this way:

  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);
    }

Bootstrapper:

<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;"/>
Silny ToJa
  • 1,815
  • 1
  • 6
  • 20