// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. namespace WixToolset.Msi { using System; using System.Diagnostics; using System.Text; using WixToolset.Core.Native; /// /// Windows Installer message types. /// [Flags] internal enum InstallMessage { /// /// Premature termination, possibly fatal out of memory. /// FatalExit = 0x00000000, /// /// Formatted error message, [1] is message number in Error table. /// Error = 0x01000000, /// /// Formatted warning message, [1] is message number in Error table. /// Warning = 0x02000000, /// /// User request message, [1] is message number in Error table. /// User = 0x03000000, /// /// Informative message for log, not to be displayed. /// Info = 0x04000000, /// /// List of files in use that need to be replaced. /// FilesInUse = 0x05000000, /// /// Request to determine a valid source location. /// ResolveSource = 0x06000000, /// /// Insufficient disk space message. /// OutOfDiskSpace = 0x07000000, /// /// Progress: start of action, [1] action name, [2] description, [3] template for ACTIONDATA messages. /// ActionStart = 0x08000000, /// /// Action data. Record fields correspond to the template of ACTIONSTART message. /// ActionData = 0x09000000, /// /// Progress bar information. See the description of record fields below. /// Progress = 0x0A000000, /// /// To enable the Cancel button set [1] to 2 and [2] to 1. To disable the Cancel button set [1] to 2 and [2] to 0. /// CommonData = 0x0B000000, /// /// Sent prior to UI initialization, no string data. /// Initilize = 0x0C000000, /// /// Sent after UI termination, no string data. /// Terminate = 0x0D000000, /// /// Sent prior to display or authored dialog or wizard. /// ShowDialog = 0x0E000000 } /// /// Windows Installer log modes. /// [Flags] internal enum InstallLogModes { /// /// Premature termination of installation. /// FatalExit = (1 << ((int)InstallMessage.FatalExit >> 24)), /// /// The error messages are logged. /// Error = (1 << ((int)InstallMessage.Error >> 24)), /// /// The warning messages are logged. /// Warning = (1 << ((int)InstallMessage.Warning >> 24)), /// /// The user requests are logged. /// User = (1 << ((int)InstallMessage.User >> 24)), /// /// The status messages that are not displayed are logged. /// Info = (1 << ((int)InstallMessage.Info >> 24)), /// /// Request to determine a valid source location. /// ResolveSource = (1 << ((int)InstallMessage.ResolveSource >> 24)), /// /// The was insufficient disk space. /// OutOfDiskSpace = (1 << ((int)InstallMessage.OutOfDiskSpace >> 24)), /// /// The start of new installation actions are logged. /// ActionStart = (1 << ((int)InstallMessage.ActionStart >> 24)), /// /// The data record with the installation action is logged. /// ActionData = (1 << ((int)InstallMessage.ActionData >> 24)), /// /// The parameters for user-interface initialization are logged. /// CommonData = (1 << ((int)InstallMessage.CommonData >> 24)), /// /// Logs the property values at termination. /// PropertyDump = (1 << ((int)InstallMessage.Progress >> 24)), /// /// Sends large amounts of information to a log file not generally useful to users. /// May be used for technical support. /// Verbose = (1 << ((int)InstallMessage.Initilize >> 24)), /// /// Sends extra debugging information, such as handle creation information, to the log file. /// ExtraDebug = (1 << ((int)InstallMessage.Terminate >> 24)), /// /// Progress bar information. This message includes information on units so far and total number of units. /// See MsiProcessMessage for an explanation of the message format. /// This message is only sent to an external user interface and is not logged. /// Progress = (1 << ((int)InstallMessage.Progress >> 24)), /// /// If this is not a quiet installation, then the basic UI has been initialized. /// If this is a full UI installation, the full UI is not yet initialized. /// This message is only sent to an external user interface and is not logged. /// Initialize = (1 << ((int)InstallMessage.Initilize >> 24)), /// /// If a full UI is being used, the full UI has ended. /// If this is not a quiet installation, the basic UI has not yet ended. /// This message is only sent to an external user interface and is not logged. /// Terminate = (1 << ((int)InstallMessage.Terminate >> 24)), /// /// Sent prior to display of the full UI dialog. /// This message is only sent to an external user interface and is not logged. /// ShowDialog = (1 << ((int)InstallMessage.ShowDialog >> 24)), /// /// Files in use information. When this message is received, a FilesInUse Dialog should be displayed. /// FilesInUse = (1 << ((int)InstallMessage.FilesInUse >> 24)) } /// /// Windows Installer UI levels. /// [Flags] internal enum InstallUILevels { /// /// No change in the UI level. However, if phWnd is not Null, the parent window can change. /// NoChange = 0, /// /// The installer chooses an appropriate user interface level. /// Default = 1, /// /// Completely silent installation. /// None = 2, /// /// Simple progress and error handling. /// Basic = 3, /// /// Authored user interface with wizard dialog boxes suppressed. /// Reduced = 4, /// /// Authored user interface with wizards, progress, and errors. /// Full = 5, /// /// If combined with the Basic value, the installer shows simple progress dialog boxes but /// does not display a Cancel button on the dialog. This prevents users from canceling the install. /// Available with Windows Installer version 2.0. /// HideCancel = 0x20, /// /// If combined with the Basic value, the installer shows simple progress /// dialog boxes but does not display any modal dialog boxes or error dialog boxes. /// ProgressOnly = 0x40, /// /// If combined with any above value, the installer displays a modal dialog /// box at the end of a successful installation or if there has been an error. /// No dialog box is displayed if the user cancels. /// EndDialog = 0x80, /// /// If this value is combined with the None value, the installer displays only the dialog /// boxes used for source resolution. No other dialog boxes are shown. This value has no /// effect if the UI level is not INSTALLUILEVEL_NONE. It is used with an external user /// interface designed to handle all of the UI except for source resolution. In this case, /// the installer handles source resolution. This value is only available with Windows Installer 2.0 and later. /// SourceResOnly = 0x100 } /// /// Represents the Windows Installer, provides wrappers to /// create the top-level objects and access their methods. /// internal sealed class Installer { /// /// Protect the constructor. /// private Installer() { } /// /// Takes the path to a file and returns a 128-bit hash of that file. /// /// Path to file that is to be hashed. /// The value in this column must be 0. This parameter is reserved for future use. /// Int array that receives the returned file hash information. internal static void GetFileHash(string filePath, int options, out int[] hash) { MsiInterop.MSIFILEHASHINFO hashInterop = new MsiInterop.MSIFILEHASHINFO(); hashInterop.FileHashInfoSize = 20; int error = MsiInterop.MsiGetFileHash(filePath, Convert.ToUInt32(options), hashInterop); if (0 != error) { throw new MsiException(error); } Debug.Assert(20 == hashInterop.FileHashInfoSize); hash = new int[4]; hash[0] = hashInterop.Data0; hash[1] = hashInterop.Data1; hash[2] = hashInterop.Data2; hash[3] = hashInterop.Data3; } /// /// Returns the version string and language string in the format that the installer /// expects to find them in the database. If you just want version information, set /// lpLangBuf and pcchLangBuf to zero. If you just want language information, set /// lpVersionBuf and pcchVersionBuf to zero. /// /// Specifies the path to the file. /// Returns the file version. Set to 0 for language information only. /// Returns the file language. Set to 0 for version information only. internal static void GetFileVersion(string filePath, out string version, out string language) { int versionLength = 20; int languageLength = 20; StringBuilder versionBuffer = new StringBuilder(versionLength); StringBuilder languageBuffer = new StringBuilder(languageLength); int error = MsiInterop.MsiGetFileVersion(filePath, versionBuffer, ref versionLength, languageBuffer, ref languageLength); if (234 == error) { versionBuffer.EnsureCapacity(++versionLength); languageBuffer.EnsureCapacity(++languageLength); error = MsiInterop.MsiGetFileVersion(filePath, versionBuffer, ref versionLength, languageBuffer, ref languageLength); } else if (1006 == error) { // file has no version or language, so no error error = 0; } if (0 != error) { throw new MsiException(error); } version = versionBuffer.ToString(); language = languageBuffer.ToString(); } /// /// Enables an external user-interface handler. /// /// Specifies a callback function. /// Specifies which messages to handle using the external message handler. /// Pointer to an application context that is passed to the callback function. /// The return value is the previously set external handler, or null if there was no previously set handler. internal static InstallUIHandler SetExternalUI(InstallUIHandler installUIHandler, int messageFilter, IntPtr context) { return MsiInterop.MsiSetExternalUI(installUIHandler, messageFilter, context); } /// /// Enables the installer's internal user interface. /// /// Specifies the level of complexity of the user interface. /// Pointer to a window. This window becomes the owner of any user interface created. /// The previous user interface level is returned. If an invalid dwUILevel is passed, then INSTALLUILEVEL_NOCHANGE is returned. internal static int SetInternalUI(int uiLevel, ref IntPtr hwnd) { return MsiInterop.MsiSetInternalUI(uiLevel, ref hwnd); } } }