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/Directory.Build.props | 11 -- src/test/dtf/Directory.Build.targets | 6 - src/test/dtf/DtfE2ETests.sln | 28 ---- 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 ------------------- src/test/dtf/SampleCA/CustomAction.config | 10 -- src/test/dtf/SampleCA/SampleCA.cs | 125 ---------------- src/test/dtf/SampleCA/SampleCA.csproj | 16 -- src/test/dtf/SampleCA/testsub/testfile.txt | 1 - 13 files changed, 719 deletions(-) delete mode 100644 src/test/dtf/Directory.Build.props delete mode 100644 src/test/dtf/Directory.Build.targets delete mode 100644 src/test/dtf/DtfE2ETests.sln 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 delete mode 100644 src/test/dtf/SampleCA/CustomAction.config delete mode 100644 src/test/dtf/SampleCA/SampleCA.cs delete mode 100644 src/test/dtf/SampleCA/SampleCA.csproj delete mode 100644 src/test/dtf/SampleCA/testsub/testfile.txt (limited to 'src/test/dtf') diff --git a/src/test/dtf/Directory.Build.props b/src/test/dtf/Directory.Build.props deleted file mode 100644 index 0035a9e6..00000000 --- a/src/test/dtf/Directory.Build.props +++ /dev/null @@ -1,11 +0,0 @@ - - - - - IntegrationDtf - false - - - - - diff --git a/src/test/dtf/Directory.Build.targets b/src/test/dtf/Directory.Build.targets deleted file mode 100644 index 4e97b6ca..00000000 --- a/src/test/dtf/Directory.Build.targets +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/test/dtf/DtfE2ETests.sln b/src/test/dtf/DtfE2ETests.sln deleted file mode 100644 index 39d8cf08..00000000 --- a/src/test/dtf/DtfE2ETests.sln +++ /dev/null @@ -1,28 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30114.105 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmbeddedUI", "EmbeddedUI\EmbeddedUI.csproj", "{864B8C50-7895-4485-AC89-900D86FD8C0D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleCA", "SampleCA\SampleCA.csproj", "{8F53B9CC-6FBE-493D-9C9A-09B2AD578CE7}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {864B8C50-7895-4485-AC89-900D86FD8C0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {864B8C50-7895-4485-AC89-900D86FD8C0D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {864B8C50-7895-4485-AC89-900D86FD8C0D}.Release|Any CPU.ActiveCfg = Debug|Any CPU - {864B8C50-7895-4485-AC89-900D86FD8C0D}.Release|Any CPU.Build.0 = Debug|Any CPU - {8F53B9CC-6FBE-493D-9C9A-09B2AD578CE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8F53B9CC-6FBE-493D-9C9A-09B2AD578CE7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8F53B9CC-6FBE-493D-9C9A-09B2AD578CE7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8F53B9CC-6FBE-493D-9C9A-09B2AD578CE7}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection -EndGlobal 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; - } - } - } -} diff --git a/src/test/dtf/SampleCA/CustomAction.config b/src/test/dtf/SampleCA/CustomAction.config deleted file mode 100644 index 700aff6f..00000000 --- a/src/test/dtf/SampleCA/CustomAction.config +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/test/dtf/SampleCA/SampleCA.cs b/src/test/dtf/SampleCA/SampleCA.cs deleted file mode 100644 index fc9f30fe..00000000 --- a/src/test/dtf/SampleCA/SampleCA.cs +++ /dev/null @@ -1,125 +0,0 @@ -namespace WixToolset.Samples -{ - using System; - using System.Collections.Generic; - using System.IO; - using WixToolset.Dtf.WindowsInstaller; - - public class SampleCA - { - [CustomAction] - public static ActionResult SampleCA1(Session session) - { - using (Record msgRec = new Record(0)) - { - msgRec[0] = "Hello from SampleCA1!" + - "\r\nCLR version is v" + Environment.Version; - session.Message(InstallMessage.Info, msgRec); - session.Message(InstallMessage.User, msgRec); - } - - session.Log("Testing summary info..."); - SummaryInfo summInfo = session.Database.SummaryInfo; - session.Log("MSI PackageCode = {0}", summInfo.RevisionNumber); - session.Log("MSI ModifyDate = {0}", summInfo.LastSaveTime); - - string testProp = session["SampleCATest"]; - session.Log("Simple property test: [SampleCATest]={0}.", testProp); - - session.Log("Testing subdirectory extraction..."); - string testFilePath = "testsub\\SampleCAs.cs"; - if (!File.Exists(testFilePath)) - { - session.Log("Subdirectory extraction failed. File not found: " + testFilePath); - return ActionResult.Failure; - } - else - { - session.Log("Found file extracted in subdirectory."); - } - - session.Log("Testing record stream extraction..."); - string tempFile = null; - try - { - tempFile = Path.GetTempFileName(); - using (View binView = session.Database.OpenView( - "SELECT `Binary`.`Data` FROM `Binary`, `CustomAction` " + - "WHERE `CustomAction`.`Target` = 'SampleCA1' AND " + - "`CustomAction`.`Source` = `Binary`.`Name`")) - { - binView.Execute(); - using (Record binRec = binView.Fetch()) - { - binRec.GetStream(1, tempFile); - } - } - - session.Log("CA binary file size: {0}", new FileInfo(tempFile).Length); - string binFileVersion = Installer.GetFileVersion(tempFile); - session.Log("CA binary file version: {0}", binFileVersion); - } - finally - { - if (tempFile != null && File.Exists(tempFile)) - { - File.Delete(tempFile); - } - } - - session.Log("Testing record stream reading..."); - using (View binView2 = session.Database.OpenView("SELECT `Data` FROM `Binary` WHERE `Name` = 'TestData'")) - { - binView2.Execute(); - using (Record binRec2 = binView2.Fetch()) - { - Stream stream = binRec2.GetStream("Data"); - string testData = new StreamReader(stream, System.Text.Encoding.UTF8).ReadToEnd(); - session.Log("Test data: " + testData); - } - } - - session.Log("Listing components"); - using (View compView = session.Database.OpenView( - "SELECT `Component` FROM `Component`")) - { - compView.Execute(); - foreach (Record compRec in compView) - { - using (compRec) - { - session.Log("\t{0}", compRec["Component"]); - } - } - } - - session.Log("Testing the ability to access an external MSI database..."); - string tempDbFile = Path.GetTempFileName(); - using (Database tempDb = new Database(tempDbFile, DatabaseOpenMode.CreateDirect)) - { - // Just create an empty database. - } - using (Database tempDb2 = new Database(tempDbFile)) - { - // See if we can open and query the database. - IList tables = tempDb2.ExecuteStringQuery("SELECT `Name` FROM `_Tables`"); - session.Log("Found " + tables.Count + " tables in the newly created database."); - } - File.Delete(tempDbFile); - - return ActionResult.Success; - } - - [CustomAction("SampleCA2")] - public static ActionResult SampleCustomAction2(Session session) - { - using (Record msgRec = new Record(0)) - { - msgRec[0] = "Hello from SampleCA2!"; - session.Message(InstallMessage.Info, msgRec); - session.Message(InstallMessage.User, msgRec); - } - return ActionResult.UserExit; - } - } -} diff --git a/src/test/dtf/SampleCA/SampleCA.csproj b/src/test/dtf/SampleCA/SampleCA.csproj deleted file mode 100644 index 866b7575..00000000 --- a/src/test/dtf/SampleCA/SampleCA.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - net20 - Sample managed custom actions - - - - - - - - - - - - diff --git a/src/test/dtf/SampleCA/testsub/testfile.txt b/src/test/dtf/SampleCA/testsub/testfile.txt deleted file mode 100644 index 8056aefd..00000000 --- a/src/test/dtf/SampleCA/testsub/testfile.txt +++ /dev/null @@ -1 +0,0 @@ -test file for testing subdirectory support and binary stream reading -- cgit v1.2.3-55-g6feb