From 913b6238417dceeb8440315e4669990756d17655 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Tue, 19 Jul 2022 15:17:10 -0500 Subject: Add WixInternalUIBootstrapperApplication as a new built-in BA. Implements 6835 --- src/test/dtf/EmbeddedUI/EmbeddedUI.config | 10 -- src/test/dtf/EmbeddedUI/EmbeddedUI.csproj | 24 --- src/test/dtf/EmbeddedUI/InstallProgressCounter.cs | 174 ---------------------- src/test/dtf/EmbeddedUI/SampleEmbeddedUI.cs | 141 ------------------ src/test/dtf/EmbeddedUI/SetupWizard.xaml | 19 --- src/test/dtf/EmbeddedUI/SetupWizard.xaml.cs | 154 ------------------- 6 files changed, 522 deletions(-) delete mode 100644 src/test/dtf/EmbeddedUI/EmbeddedUI.config delete mode 100644 src/test/dtf/EmbeddedUI/EmbeddedUI.csproj delete mode 100644 src/test/dtf/EmbeddedUI/InstallProgressCounter.cs delete mode 100644 src/test/dtf/EmbeddedUI/SampleEmbeddedUI.cs delete mode 100644 src/test/dtf/EmbeddedUI/SetupWizard.xaml delete mode 100644 src/test/dtf/EmbeddedUI/SetupWizard.xaml.cs (limited to 'src/test/dtf/EmbeddedUI') diff --git a/src/test/dtf/EmbeddedUI/EmbeddedUI.config b/src/test/dtf/EmbeddedUI/EmbeddedUI.config deleted file mode 100644 index 700aff6f..00000000 --- a/src/test/dtf/EmbeddedUI/EmbeddedUI.config +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/test/dtf/EmbeddedUI/EmbeddedUI.csproj b/src/test/dtf/EmbeddedUI/EmbeddedUI.csproj deleted file mode 100644 index a6339220..00000000 --- a/src/test/dtf/EmbeddedUI/EmbeddedUI.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - net35 - Sample managed embedded external UI - true - - - - - - - - - - - - - - - - - - - diff --git a/src/test/dtf/EmbeddedUI/InstallProgressCounter.cs b/src/test/dtf/EmbeddedUI/InstallProgressCounter.cs deleted file mode 100644 index 3d75081c..00000000 --- a/src/test/dtf/EmbeddedUI/InstallProgressCounter.cs +++ /dev/null @@ -1,174 +0,0 @@ -namespace WixToolset.Samples.EmbeddedUI -{ - using System; - using WixToolset.Dtf.WindowsInstaller; - - /// - /// Tracks MSI progress messages and converts them to usable progress. - /// - public class InstallProgressCounter - { - private int total; - private int completed; - private int step; - private bool moveForward; - private bool enableActionData; - private int progressPhase; - private double scriptPhaseWeight; - - public InstallProgressCounter() : this(0.3) - { - } - - public InstallProgressCounter(double scriptPhaseWeight) - { - if (!(0 <= scriptPhaseWeight && scriptPhaseWeight <= 1)) - { - throw new ArgumentOutOfRangeException("scriptPhaseWeight"); - } - - this.scriptPhaseWeight = scriptPhaseWeight; - } - - /// - /// Gets a number between 0 and 1 that indicates the overall installation progress. - /// - public double Progress { get; private set; } - - public void ProcessMessage(InstallMessage messageType, Record messageRecord) - { - // This MSI progress-handling code was mostly borrowed from burn and translated from C++ to C#. - - switch (messageType) - { - case InstallMessage.ActionStart: - if (this.enableActionData) - { - this.enableActionData = false; - } - break; - - case InstallMessage.ActionData: - if (this.enableActionData) - { - if (this.moveForward) - { - this.completed += this.step; - } - else - { - this.completed -= this.step; - } - - this.UpdateProgress(); - } - break; - - case InstallMessage.Progress: - this.ProcessProgressMessage(messageRecord); - break; - } - } - - private void ProcessProgressMessage(Record progressRecord) - { - // This MSI progress-handling code was mostly borrowed from burn and translated from C++ to C#. - - if (progressRecord == null || progressRecord.FieldCount == 0) - { - return; - } - - int fieldCount = progressRecord.FieldCount; - int progressType = progressRecord.GetInteger(1); - string progressTypeString = String.Empty; - switch (progressType) - { - case 0: // Master progress reset - if (fieldCount < 4) - { - return; - } - - this.progressPhase++; - - this.total = progressRecord.GetInteger(2); - if (this.progressPhase == 1) - { - // HACK!!! this is a hack courtesy of the Windows Installer team. It seems the script planning phase - // is always off by "about 50". So we'll toss an extra 50 ticks on so that the standard progress - // doesn't go over 100%. If there are any custom actions, they may blow the total so we'll call this - // "close" and deal with the rest. - this.total += 50; - } - - this.moveForward = (progressRecord.GetInteger(3) == 0); - this.completed = (this.moveForward ? 0 : this.total); // if forward start at 0, if backwards start at max - this.enableActionData = false; - - this.UpdateProgress(); - break; - - case 1: // Action info - if (fieldCount < 3) - { - return; - } - - if (progressRecord.GetInteger(3) == 0) - { - this.enableActionData = false; - } - else - { - this.enableActionData = true; - this.step = progressRecord.GetInteger(2); - } - break; - - case 2: // Progress report - if (fieldCount < 2 || this.total == 0 || this.progressPhase == 0) - { - return; - } - - if (this.moveForward) - { - this.completed += progressRecord.GetInteger(2); - } - else - { - this.completed -= progressRecord.GetInteger(2); - } - - this.UpdateProgress(); - break; - - case 3: // Progress total addition - this.total += progressRecord.GetInteger(2); - break; - } - } - - private void UpdateProgress() - { - if (this.progressPhase < 1 || this.total == 0) - { - this.Progress = 0; - } - else if (this.progressPhase == 1) - { - this.Progress = this.scriptPhaseWeight * Math.Min(this.completed, this.total) / this.total; - } - else if (this.progressPhase == 2) - { - this.Progress = this.scriptPhaseWeight + - (1 - this.scriptPhaseWeight) * Math.Min(this.completed, this.total) / this.total; - } - else - { - this.Progress = 1; - } - } - } -} diff --git a/src/test/dtf/EmbeddedUI/SampleEmbeddedUI.cs b/src/test/dtf/EmbeddedUI/SampleEmbeddedUI.cs deleted file mode 100644 index ae86dc97..00000000 --- a/src/test/dtf/EmbeddedUI/SampleEmbeddedUI.cs +++ /dev/null @@ -1,141 +0,0 @@ -namespace WixToolset.Samples.EmbeddedUI -{ - using System; - using System.Collections.Generic; - using System.Configuration; - using System.Threading; - using System.Windows; - using System.Windows.Threading; - using WixToolset.Dtf.WindowsInstaller; - using Application = System.Windows.Application; - - public class SampleEmbeddedUI : IEmbeddedUI - { - private bool isMaintenance; - private Thread appThread; - private Application app; - private SetupWizard setupWizard; - private ManualResetEvent installStartEvent; - private ManualResetEvent installExitEvent; - - /// - /// Initializes the embedded UI. - /// - /// Handle to the installer which can be used to get and set properties. - /// The handle is only valid for the duration of this method call. - /// Path to the directory that contains all the files from the MsiEmbeddedUI table. - /// On entry, contains the current UI level for the installation. After this - /// method returns, the installer resets the UI level to the returned value of this parameter. - /// True if the embedded UI was successfully initialized; false if the installation - /// should continue without the embedded UI. - /// The installation was canceled by the user. - /// The embedded UI failed to initialize and - /// causes the installation to fail. - public bool Initialize(Session session, string resourcePath, ref InstallUIOptions internalUILevel) - { - if (session != null) - { - if ((internalUILevel & InstallUIOptions.Full) != InstallUIOptions.Full) - { - // Don't show custom UI when the UI level is set to basic. - return false; - - // An embedded UI could display an alternate dialog sequence for reduced or - // basic modes, but it's not implemented here. We'll just fall back to the - // built-in MSI basic UI. - } - - if (String.Equals(session["REMOVE"], "All", StringComparison.OrdinalIgnoreCase)) - { - // Don't show custom UI when uninstall was specified on the command line. - return false; - } - - this.isMaintenance = session.EvaluateCondition("Installed"); - } - - // Start the setup wizard on a separate thread. - this.installStartEvent = new ManualResetEvent(false); - this.installExitEvent = new ManualResetEvent(false); - this.appThread = new Thread(this.Run); - this.appThread.SetApartmentState(ApartmentState.STA); - this.appThread.Start(); - - // Wait for the setup wizard to either kickoff the install or prematurely exit. - int waitResult = WaitHandle.WaitAny(new WaitHandle[] { this.installStartEvent, this.installExitEvent }); - if (waitResult == 1) - { - // The setup wizard set the exit event instead of the start event. Cancel the installation. - throw new InstallCanceledException(); - } - else - { - switch (this.setupWizard.Operation) - { - case SetupOperationType.Repair: - session["REINSTALL"] = "ALL"; - break; - case SetupOperationType.Uninstall: - session["REMOVE"] = "ALL"; - break; - } - - // Start the installation with a silenced internal UI. - // This "embedded external UI" will handle message types except for source resolution. - internalUILevel = InstallUIOptions.NoChange | InstallUIOptions.SourceResolutionOnly; - return true; - } - } - - /// - /// Processes information and progress messages sent to the user interface. - /// - /// Message type. - /// Record that contains message data. - /// Message box buttons. - /// Message box icon. - /// Message box default button. - /// Result of processing the message. - public MessageResult ProcessMessage(InstallMessage messageType, Record messageRecord, - MessageButtons buttons, MessageIcon icon, MessageDefaultButton defaultButton) - { - // Synchronously send the message to the setup wizard window on its thread. - object result = this.setupWizard.Dispatcher.Invoke(DispatcherPriority.Send, - new Func(delegate() - { - return this.setupWizard.ProcessMessage(messageType, messageRecord, buttons, icon, defaultButton); - })); - return (MessageResult) result; - } - - /// - /// Shuts down the embedded UI at the end of the installation. - /// - /// - /// If the installation was canceled during initialization, this method will not be called. - /// If the installation was canceled or failed at any later point, this method will be called at the end. - /// - public void Shutdown() - { - // Wait for the user to exit the setup wizard. - this.setupWizard.Dispatcher.BeginInvoke(DispatcherPriority.Normal, - new Action(delegate() - { - this.setupWizard.EnableExit(); - })); - this.appThread.Join(); - } - - /// - /// Creates the setup wizard and runs the application thread. - /// - private void Run() - { - this.app = new Application(); - this.setupWizard = new SetupWizard(this.installStartEvent, this.isMaintenance); - this.setupWizard.InitializeComponent(); - this.app.Run(this.setupWizard); - this.installExitEvent.Set(); - } - } -} diff --git a/src/test/dtf/EmbeddedUI/SetupWizard.xaml b/src/test/dtf/EmbeddedUI/SetupWizard.xaml deleted file mode 100644 index 97e406c2..00000000 --- a/src/test/dtf/EmbeddedUI/SetupWizard.xaml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/src/test/dtf/EmbeddedUI/SetupWizard.xaml.cs b/src/test/dtf/EmbeddedUI/SetupWizard.xaml.cs deleted file mode 100644 index a4345481..00000000 --- a/src/test/dtf/EmbeddedUI/SetupWizard.xaml.cs +++ /dev/null @@ -1,154 +0,0 @@ -namespace WixToolset.Samples.EmbeddedUI -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using System.Threading; - using System.Windows; - using System.Windows.Controls; - using System.Windows.Data; - using System.Windows.Documents; - using System.Windows.Input; - using System.Windows.Media; - using System.Windows.Media.Imaging; - using System.Windows.Navigation; - using System.Windows.Shapes; - using WixToolset.Dtf.WindowsInstaller; - - public enum SetupOperationType - { - Install, - Repair, - Uninstall - } - - /// - /// Interaction logic for SetupWizard.xaml - /// - public partial class SetupWizard : Window - { - private bool isMaintenance; - private ManualResetEvent installStartEvent; - private InstallProgressCounter progressCounter; - private bool canceled; - - public SetupOperationType Operation { get; private set; } - - public SetupWizard(ManualResetEvent installStartEvent, bool isMaintenance) - { - this.installStartEvent = installStartEvent; - this.progressCounter = new InstallProgressCounter(0.5); - this.isMaintenance = isMaintenance; - - this.Loaded += this.SetupWizard_Loaded; - } - - private void SetupWizard_Loaded(object sender, RoutedEventArgs e) - { - this.Loaded -= this.SetupWizard_Loaded; - - if (this.isMaintenance) - { - this.installButton.Visibility = Visibility.Hidden; - this.repairButton.Visibility = Visibility.Visible; - this.uninstallButton.Visibility = Visibility.Visible; - } - } - - public MessageResult ProcessMessage(InstallMessage messageType, Record messageRecord, - MessageButtons buttons, MessageIcon icon, MessageDefaultButton defaultButton) - { - try - { - this.progressCounter.ProcessMessage(messageType, messageRecord); - this.progressBar.Value = this.progressBar.Minimum + - this.progressCounter.Progress * (this.progressBar.Maximum - this.progressBar.Minimum); - this.progressLabel.Content = "" + (int) Math.Round(100 * this.progressCounter.Progress) + "%"; - - switch (messageType) - { - case InstallMessage.Error: - case InstallMessage.Warning: - case InstallMessage.Info: - string message = String.Format("{0}: {1}", messageType, messageRecord); - this.LogMessage(message); - break; - } - - if (this.canceled) - { - this.canceled = false; - return MessageResult.Cancel; - } - } - catch (Exception ex) - { - this.LogMessage(ex.ToString()); - this.LogMessage(ex.StackTrace); - } - - return MessageResult.OK; - } - - private void LogMessage(string message) - { - this.messagesTextBox.Text += Environment.NewLine + message; - this.messagesTextBox.ScrollToEnd(); - } - - internal void EnableExit() - { - this.progressBar.Visibility = Visibility.Hidden; - this.progressLabel.Visibility = Visibility.Hidden; - this.cancelButton.Visibility = Visibility.Hidden; - this.exitButton.Visibility = Visibility.Visible; - } - - private void installButton_Click(object sender, RoutedEventArgs e) - { - this.Operation = SetupOperationType.Install; - this.StartInstall(); - } - - private void repairButton_Click(object sender, RoutedEventArgs e) - { - this.Operation = SetupOperationType.Repair; - this.StartInstall(); - } - - private void uninstallButton_Click(object sender, RoutedEventArgs e) - { - this.Operation = SetupOperationType.Uninstall; - this.StartInstall(); - } - - private void StartInstall() - { - this.installButton.Visibility = Visibility.Hidden; - this.repairButton.Visibility = Visibility.Hidden; - this.uninstallButton.Visibility = Visibility.Hidden; - this.progressBar.Visibility = Visibility.Visible; - this.progressLabel.Visibility = Visibility.Visible; - this.installStartEvent.Set(); - } - - private void exitButton_Click(object sender, RoutedEventArgs e) - { - this.Close(); - } - - private void cancelButton_Click(object sender, RoutedEventArgs e) - { - if (this.installButton.Visibility == Visibility.Visible) - { - this.Close(); - } - else - { - this.canceled = true; - this.cancelButton.IsEnabled = false; - } - } - } -} -- cgit v1.2.3-55-g6feb