/// <summary> /// [MSI 3.1] Enables a record-based external user-interface handler. This external UI handler is called /// before the normal internal user-interface handler. The external UI handler has the option to suppress /// the internal UI by returning a non-zero value to indicate that it has handled the messages. /// </summary> /// <param name="uiHandler">A callback delegate that handles the UI messages</param> /// <param name="messageFilter">Specifies which messages to handle using the external message handler. /// If the external handler returns a non-zero result, then that message will not be sent to the UI, /// instead the message will be logged if logging has been enabled.</param> /// <returns>The previously set external handler, or null if there was no previously set handler</returns> /// <remarks><p> /// To restore the previous UI handler, a second call is made to SetExternalUI using the /// ExternalUIHandler returned by the first call to SetExternalUI and specifying /// <see cref="InstallLogModes.None"/> as the message filter. /// </p><p> /// The external user interface handler does not have full control over the external user /// interface unless <see cref="SetInternalUI(InstallUIOptions)"/> is called with the uiLevel parameter set to /// <see cref="InstallUIOptions.Silent"/>. If SetInternalUI is not called, the internal user /// interface level defaults to <see cref="InstallUIOptions.Basic"/>. As a result, any message not /// handled by the external user interface handler is handled by Windows Installer. The initial /// "Preparing to install..." dialog always appears even if the external user interface /// handler handles all messages. /// </p><p> /// SetExternalUI should only be called from a bootstrapping application. You cannot call /// it from a custom action /// </p><p> /// Win32 MSI API: /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisetexternaluirecord.asp">MsiSetExternalUIRecord</a> /// </p></remarks> public static ExternalUIRecordHandler SetExternalUI(ExternalUIRecordHandler uiHandler, InstallLogModes messageFilter) { NativeExternalUIRecordHandler nativeHandler = null; if (uiHandler != null) { nativeHandler = new ExternalUIRecordProxy(uiHandler).ProxyHandler; Installer.externalUIHandlers.Add(nativeHandler); } NativeExternalUIRecordHandler oldNativeHandler; uint ret = NativeMethods.MsiSetExternalUIRecord(nativeHandler, (uint)messageFilter, IntPtr.Zero, out oldNativeHandler); if (ret != 0) { Installer.externalUIHandlers.Remove(nativeHandler); throw InstallerException.ExceptionFromReturnCode(ret); } if (oldNativeHandler != null && oldNativeHandler.Target is ExternalUIRecordProxy) { Installer.externalUIHandlers.Remove(oldNativeHandler); return(((ExternalUIRecordProxy)oldNativeHandler.Target).Handler); } else { return(null); } }
/// <summary> /// Sets up the user interface handlers. /// </summary> protected override void BeginProcessing() { // Set up the UI handlers. this.previousInternalUI = Installer.SetInternalUI(InstallUIOptions.Silent); this.previousExternalUI = Installer.SetExternalUI(this.OnMessage, InstallLogModes.FatalExit | InstallLogModes.Error | InstallLogModes.Warning | InstallLogModes.User); base.BeginProcessing(); }
/// <summary> /// Sets up an external UI handler and runs the package. /// </summary> /// <param name="passes">Number of passing tests.</param> /// <param name="failures">Number of failing tests.</param> public void RunTests(out int passes, out int failures) { InstallUIOptions previousUILevel = Installer.SetInternalUI(InstallUIOptions.Silent); ExternalUIRecordHandler previousUIHandler = Installer.SetExternalUI(this.UIRecordHandler, InstallLogModes.FatalExit | InstallLogModes.Error | /*InstallLogModes.Info | */ InstallLogModes.User | InstallLogModes.ActionStart); try { foreach (string package in this.InputFiles) { using (this.session = Installer.OpenPackage(package, false)) { IList <string> mutations = this.session.Database.ExecuteStringQuery("SELECT DISTINCT `Mutation` FROM `WixUnitTest`"); foreach (string mutation in mutations) { if (!String.IsNullOrEmpty(mutation)) { this.OnMessage(NitVerboses.RunningMutation(mutation)); this.session[Constants.LuxMutationRunningProperty] = mutation; } try { this.session.DoAction("INSTALL"); } catch (InstallCanceledException) { ; // expected } catch (InstallerException ex) { this.OnMessage(NitErrors.PackageFailed(ex.Message)); ++this.failures; } } } } } finally { Installer.SetExternalUI(previousUIHandler, InstallLogModes.None); Installer.SetInternalUI(previousUILevel); } passes = this.passes; failures = this.failures; }
internal UserInterfaceHandler(ExternalUIRecordHandler handler, bool force) { var internalUI = InstallUIOptions.Silent; if (force) { internalUI |= InstallUIOptions.SourceResolutionOnly | InstallUIOptions.UacOnly; } var externalUI = InstallLogModes.ActionStart | InstallLogModes.ActionData | InstallLogModes.CommonData | InstallLogModes.Error | InstallLogModes.FatalExit | InstallLogModes.Info | InstallLogModes.Initialize | InstallLogModes.Progress | InstallLogModes.User | InstallLogModes.Verbose | InstallLogModes.Warning; // Set up the internal and external UI handling. this.previousInternalUI = Installer.SetInternalUI(internalUI); this.previousExternalUI = Installer.SetExternalUI(handler, externalUI); }
internal ExternalUIRecordProxy(ExternalUIRecordHandler handler) { this.handler = handler; }
/// <summary> /// [MSI 3.1] Enables a record-based external user-interface handler. This external UI handler is called /// before the normal internal user-interface handler. The external UI handler has the option to suppress /// the internal UI by returning a non-zero value to indicate that it has handled the messages. /// </summary> /// <param name="uiHandler">A callback delegate that handles the UI messages</param> /// <param name="messageFilter">Specifies which messages to handle using the external message handler. /// If the external handler returns a non-zero result, then that message will not be sent to the UI, /// instead the message will be logged if logging has been enabled.</param> /// <returns>The previously set external handler, or null if there was no previously set handler</returns> /// <remarks><p> /// To restore the previous UI handler, a second call is made to SetExternalUI using the /// ExternalUIHandler returned by the first call to SetExternalUI and specifying /// <see cref="InstallLogModes.None"/> as the message filter. /// </p><p> /// The external user interface handler does not have full control over the external user /// interface unless <see cref="SetInternalUI(InstallUIOptions)"/> is called with the uiLevel parameter set to /// <see cref="InstallUIOptions.Silent"/>. If SetInternalUI is not called, the internal user /// interface level defaults to <see cref="InstallUIOptions.Basic"/>. As a result, any message not /// handled by the external user interface handler is handled by Windows Installer. The initial /// "Preparing to install..." dialog always appears even if the external user interface /// handler handles all messages. /// </p><p> /// SetExternalUI should only be called from a bootstrapping application. You cannot call /// it from a custom action /// </p><p> /// Win32 MSI API: /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisetexternaluirecord.asp">MsiSetExternalUIRecord</a> /// </p></remarks> public static ExternalUIRecordHandler SetExternalUI(ExternalUIRecordHandler uiHandler, InstallLogModes messageFilter) { NativeExternalUIRecordHandler nativeHandler = null; if (uiHandler != null) { nativeHandler = new ExternalUIRecordProxy(uiHandler).ProxyHandler; Installer.externalUIHandlers.Add(nativeHandler); } NativeExternalUIRecordHandler oldNativeHandler; uint ret = NativeMethods.MsiSetExternalUIRecord(nativeHandler, (uint) messageFilter, IntPtr.Zero, out oldNativeHandler); if (ret != 0) { Installer.externalUIHandlers.Remove(nativeHandler); throw InstallerException.ExceptionFromReturnCode(ret); } if (oldNativeHandler != null && oldNativeHandler.Target is ExternalUIRecordProxy) { Installer.externalUIHandlers.Remove(oldNativeHandler); return ((ExternalUIRecordProxy) oldNativeHandler.Target).Handler; } else { return null; } }
[Ignore] // Requires elevation. public void InstallerTransactTwoProducts() { string dbFile1 = "InstallerTransactProduct1.msi"; string dbFile2 = "InstallerTransactProduct2.msi"; string productCode1; string productCode2; using (Database db1 = new Database(dbFile1, DatabaseOpenMode.CreateDirect)) { WindowsInstallerUtils.InitializeProductDatabase(db1); WindowsInstallerUtils.CreateTestProduct(db1); productCode1 = db1.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0]; db1.Commit(); } using (Database db2 = new Database(dbFile2, DatabaseOpenMode.CreateDirect)) { WindowsInstallerUtils.InitializeProductDatabase(db2); WindowsInstallerUtils.CreateTestProduct(db2); productCode2 = db2.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0]; db2.Commit(); } ProductInstallation installation1 = new ProductInstallation(productCode1); ProductInstallation installation2 = new ProductInstallation(productCode2); Assert.IsFalse(installation1.IsInstalled, "Checking that product 1 is not installed before starting."); Assert.IsFalse(installation2.IsInstalled, "Checking that product 2 is not installed before starting."); Installer.SetInternalUI(InstallUIOptions.Silent); ExternalUIHandler prevHandler = Installer.SetExternalUI(WindowsInstallerTest.ExternalUILogger, InstallLogModes.FatalExit | InstallLogModes.Error | InstallLogModes.Warning | InstallLogModes.User | InstallLogModes.Info | InstallLogModes.ResolveSource | InstallLogModes.OutOfDiskSpace | InstallLogModes.ActionStart | InstallLogModes.ActionData | InstallLogModes.CommonData | InstallLogModes.Progress | InstallLogModes.Initialize | InstallLogModes.Terminate | InstallLogModes.ShowDialog); Assert.IsNull(prevHandler, "Checking that returned previous UI handler is null."); Transaction transaction = new Transaction("TestInstallTransaction", TransactionAttributes.None); Exception caughtEx = null; try { Installer.InstallProduct(dbFile1, String.Empty); } catch (Exception ex) { caughtEx = ex; } Assert.IsNull(caughtEx, "Exception thrown while installing product 1: " + caughtEx); Console.WriteLine(); Console.WriteLine("==================================================================="); Console.WriteLine(); try { Installer.InstallProduct(dbFile2, String.Empty); } catch (Exception ex) { caughtEx = ex; } Assert.IsNull(caughtEx, "Exception thrown while installing product 2: " + caughtEx); transaction.Commit(); transaction.Close(); prevHandler = Installer.SetExternalUI(prevHandler, InstallLogModes.None); Assert.AreEqual <ExternalUIHandler>(WindowsInstallerTest.ExternalUILogger, prevHandler, "Checking that previously-set UI handler is returned."); Assert.IsTrue(installation1.IsInstalled, "Checking that product 1 is installed."); Assert.IsTrue(installation2.IsInstalled, "Checking that product 2 is installed."); Console.WriteLine(); Console.WriteLine(); Console.WriteLine(); Console.WriteLine("==================================================================="); Console.WriteLine("==================================================================="); Console.WriteLine(); Console.WriteLine(); Console.WriteLine(); ExternalUIRecordHandler prevRecHandler = Installer.SetExternalUI(WindowsInstallerTest.ExternalUIRecordLogger, InstallLogModes.FatalExit | InstallLogModes.Error | InstallLogModes.Warning | InstallLogModes.User | InstallLogModes.Info | InstallLogModes.ResolveSource | InstallLogModes.OutOfDiskSpace | InstallLogModes.ActionStart | InstallLogModes.ActionData | InstallLogModes.CommonData | InstallLogModes.Progress | InstallLogModes.Initialize | InstallLogModes.Terminate | InstallLogModes.ShowDialog); Assert.IsNull(prevRecHandler, "Checking that returned previous UI record handler is null."); transaction = new Transaction("TestUninstallTransaction", TransactionAttributes.None); try { Installer.InstallProduct(dbFile1, "REMOVE=All"); } catch (Exception ex) { caughtEx = ex; } Assert.IsNull(caughtEx, "Exception thrown while removing product 1: " + caughtEx); try { Installer.InstallProduct(dbFile2, "REMOVE=All"); } catch (Exception ex) { caughtEx = ex; } Assert.IsNull(caughtEx, "Exception thrown while removing product 2: " + caughtEx); transaction.Commit(); transaction.Close(); Assert.IsFalse(installation1.IsInstalled, "Checking that product 1 is not installed after removing."); Assert.IsFalse(installation2.IsInstalled, "Checking that product 2 is not installed after removing."); prevRecHandler = Installer.SetExternalUI(prevRecHandler, InstallLogModes.None); Assert.AreEqual <ExternalUIRecordHandler>(WindowsInstallerTest.ExternalUIRecordLogger, prevRecHandler, "Checking that previously-set UI record handler is returned."); }