/// <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> /// [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; } }