using System;
using System.Runtime.InteropServices;
using System.Text;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
namespace Vanara.PInvoke
{
/// Items from the Msi.dll
public static partial class Msi
{
///
/// A value returned from when the field is null or if the field is a string that cannot be
/// converted to an integer.
///
public const int MSI_NULL_INTEGER = unchecked((int)0x80000000);
/// Create a new database, transact mode read/write.
public static readonly IntPtr MSIDBOPEN_CREATE = (IntPtr)3;
/// Create a new database, direct mode read/write.
public static readonly IntPtr MSIDBOPEN_CREATEDIRECT = (IntPtr)4;
/// Open a database direct read/write without transaction.
public static readonly IntPtr MSIDBOPEN_DIRECT = (IntPtr)2;
/// Add this flag to indicate a patch file.
public static readonly IntPtr MSIDBOPEN_PATCHFILE = (IntPtr)(32 / IntPtr.Size);
/// Open a database read-only, no persistent changes.
public static readonly IntPtr MSIDBOPEN_READONLY = (IntPtr)0;
/// Open a database read/write in transaction mode.
public static readonly IntPtr MSIDBOPEN_TRANSACT = (IntPtr)1;
/// Specifies a flag indicating what type of information is needed.
[PInvokeData("msiquery.h")]
public enum MSICOLINFO
{
/// Column names are returned.
MSICOLINFO_NAMES = 0, // return column names
/// Definitions are returned.
MSICOLINFO_TYPES = 1, // return column definitions, datatype code followed by width
}
/// Evaluation result of a conditional expression.
[PInvokeData("msiquery.h")]
public enum MSICONDITION
{
/// Expression evaluates to False
MSICONDITION_FALSE = 0, // expression evaluates to False
/// Expression evaluates to True
MSICONDITION_TRUE = 1, // expression evaluates to True
/// No expression present
MSICONDITION_NONE = 2, // no expression present
/// Syntax error in expression
MSICONDITION_ERROR = 3, // syntax error in expression
}
/// Specifies the value the function uses to determine disk space requirements.
[PInvokeData("msiquery.h")]
public enum MSICOSTTREE
{
/// The feature only is included in the cost.
MSICOSTTREE_SELFONLY = 0,
/// The children of the indicated feature are included in the cost.
MSICOSTTREE_CHILDREN = 1,
/// he parent features of the indicated feature are included in the cost.
MSICOSTTREE_PARENTS = 2,
/// Reserved for future use
MSICOSTTREE_RESERVED = 3, // Reserved for future use
}
/// The error that occurred in the MsiViewModify function.
[PInvokeData("msiquery.h")]
public enum MSIDBERROR
{
/// An argument was invalid.
MSIDBERROR_INVALIDARG = -3, // invalid argument
/// The buffer was too small to receive data.
MSIDBERROR_MOREDATA = -2, // buffer too small
/// The function failed.
MSIDBERROR_FUNCTIONERROR = -1, // function error
/// The function completed successfully with no errors.
MSIDBERROR_NOERROR = 0, // no error
/// The new record duplicates primary keys of the existing record in a table.
MSIDBERROR_DUPLICATEKEY = 1, // new record duplicates primary keys of existing record in table
/// There are no null values allowed; or the column is about to be deleted, but is referenced by another row.
MSIDBERROR_REQUIRED = 2, // non-nullable column, no null values allowed
/// The corresponding record in a foreign table was not found.
MSIDBERROR_BADLINK = 3, // corresponding record in foreign table not found
/// The data is greater than the maximum value allowed.
MSIDBERROR_OVERFLOW = 4, // data greater than maximum value allowed
/// The data is less than the minimum value allowed.
MSIDBERROR_UNDERFLOW = 5, // data less than minimum value allowed
/// The data is not a member of the values permitted in the set.
MSIDBERROR_NOTINSET = 6, // data not a member of the values permitted in the set
/// An invalid version string was supplied.
MSIDBERROR_BADVERSION = 7, // invalid version string
/// The case was invalid. The case must be all uppercase or all lowercase.
MSIDBERROR_BADCASE = 8, // invalid case, must be all upper-case or all lower-case
/// An invalid GUID was supplied.
MSIDBERROR_BADGUID = 9, // invalid GUID
/// An invalid wildcard file name was supplied, or the use of wildcards was invalid.
MSIDBERROR_BADWILDCARD = 10, // invalid wildcardfilename or use of wildcards
/// An invalid identifier was supplied.
MSIDBERROR_BADIDENTIFIER = 11, // bad identifier
/// Invalid language IDs were supplied.
MSIDBERROR_BADLANGUAGE = 12, // bad language Id(s)
/// An invalid file name was supplied.
MSIDBERROR_BADFILENAME = 13, // bad filename
/// An invalid path was supplied.
MSIDBERROR_BADPATH = 14, // bad path
/// An invalid conditional statement was supplied.
MSIDBERROR_BADCONDITION = 15, // bad conditional statement
/// An invalid format string was supplied.
MSIDBERROR_BADFORMATTED = 16, // bad format string
/// An invalid template string was supplied.
MSIDBERROR_BADTEMPLATE = 17, // bad template string
/// An invalid string was supplied in the DefaultDir column of the Directory table.
MSIDBERROR_BADDEFAULTDIR = 18, // bad string in DefaultDir column of Directory table
/// An invalid registry path string was supplied.
MSIDBERROR_BADREGPATH = 19, // bad registry path string
/// An invalid string was supplied in the CustomSource column of the CustomAction table.
MSIDBERROR_BADCUSTOMSOURCE = 20, // bad string in CustomSource column of CustomAction table
/// An invalid property string was supplied.
MSIDBERROR_BADPROPERTY = 21, // bad property string
/// The _Validation table is missing a reference to a column.
MSIDBERROR_MISSINGDATA = 22, // _Validation table missing reference to column
/// The category column of the _Validation table for the column is invalid.
MSIDBERROR_BADCATEGORY = 23, // Category column of _Validation table for column is invalid
/// An invalid cabinet name was supplied.
MSIDBERROR_BADKEYTABLE = 24, // table in KeyTable column of _Validation table could not be found/loaded
/// The table in the Keytable column of the _Validation table was not found or loaded.
MSIDBERROR_BADMAXMINVALUES = 25, // value in MaxValue column of _Validation table is less than value in MinValue column
/// The value in the MaxValue column of the _Validation table is less than the value in the MinValue column.
MSIDBERROR_BADCABINET = 26, // bad cabinet name
/// An invalid shortcut target name was supplied.
MSIDBERROR_BADSHORTCUT = 27, // bad shortcut target
/// The string is too long for the length specified by the column definition.
MSIDBERROR_STRINGOVERFLOW = 28, // string overflow (greater than length allowed in column def)
/// An invalid localization attribute was supplied. (Primary keys cannot be localized.)
MSIDBERROR_BADLOCALIZEATTRIB = 29 // invalid localization attribute (primary keys cannot be localized)
}
/// The state of the database.
[PInvokeData("msiquery.h")]
public enum MSIDBSTATE
{
/// Invalid database handle
MSIDBSTATE_ERROR = -1, // invalid database handle
/// Database open read-only, no persistent changes
MSIDBSTATE_READ = 0, // database open read-only, no persistent changes
/// The database is readable and updatable.
MSIDBSTATE_WRITE = 1, // database readable and updatable
}
/// Specifies the modify mode.
[PInvokeData("msiquery.h")]
public enum MSIMODIFY
{
///
/// Refreshes the information in the supplied record without changing the position in the result set and without affecting
/// subsequent fetch operations. The record may then be used for subsequent Update, Delete, and Refresh. All primary key columns
/// of the table must be in the query and the record must have at least as many fields as the query. Seek cannot be used with
/// multi-table queries. This mode cannot be used with a view containing joins. See also the remarks.
///
MSIMODIFY_SEEK = -1, // reposition to current record primary key
///
/// Refreshes the information in the record. Must first call MsiViewFetch with the same record. Fails for a deleted row. Works
/// with read-write and read-only records.
///
MSIMODIFY_REFRESH = 0, // refetch current record data
///
/// Inserts a record. Fails if a row with the same primary keys exists. Fails with a read-only database. This mode cannot be
/// used with a view containing joins.
///
MSIMODIFY_INSERT = 1, // insert new record, fails if matching key exists
///
/// Updates an existing record. Nonprimary keys only. Must first call MsiViewFetch. Fails with a deleted record. Works only with
/// read-write records.
///
MSIMODIFY_UPDATE = 2, // update existing non-key data of fetched record
///
/// Writes current data in the cursor to a table row. Updates record if the primary keys match an existing row and inserts if
/// they do not match. Fails with a read-only database. This mode cannot be used with a view containing joins.
///
MSIMODIFY_ASSIGN = 3, // insert record, replacing any existing record
///
/// Updates or deletes and inserts a record into a table. Must first call MsiViewFetch with the same record. Updates record if
/// the primary keys are unchanged. Deletes old row and inserts new if primary keys have changed. Fails with a read-only
/// database. This mode cannot be used with a view containing joins.
///
MSIMODIFY_REPLACE = 4, // update record, delete old if primary key edit
///
/// Inserts or validates a record in a table. Inserts if primary keys do not match any row and validates if there is a match.
/// Fails if the record does not match the data in the table. Fails if there is a record with a duplicate key that is not
/// identical. Works only with read-write records. This mode cannot be used with a view containing joins.
///
MSIMODIFY_MERGE = 5, // fails if record with duplicate key not identical
///
/// Remove a row from the table. You must first call the MsiViewFetch function with the same record. Fails if the row has been
/// deleted. Works only with read-write records. This mode cannot be used with a view containing joins.
///
MSIMODIFY_DELETE = 6, // remove row referenced by this record from table
///
/// Inserts a temporary record. The information is not persistent. Fails if a row with the same primary key exists. Works only
/// with read-write records. This mode cannot be used with a view containing joins.
///
MSIMODIFY_INSERT_TEMPORARY = 7, // insert a temporary record
///
/// Validates a record. Does not validate across joins. You must first call the MsiViewFetch function with the same record.
/// Obtain validation errors with MsiViewGetError. Works with read-write and read-only records. This mode cannot be used with a
/// view containing joins.
///
MSIMODIFY_VALIDATE = 8, // validate a fetched record
///
/// Validate a new record. Does not validate across joins. Checks for duplicate keys. Obtain validation errors by calling
/// MsiViewGetError. Works with read-write and read-only records. This mode cannot be used with a view containing joins.
///
MSIMODIFY_VALIDATE_NEW = 9, // validate a new record
///
/// Validates fields of a fetched or new record. Can validate one or more fields of an incomplete record. Obtain validation
/// errors by calling MsiViewGetError. Works with read-write and read-only records. This mode cannot be used with a view
/// containing joins.
///
MSIMODIFY_VALIDATE_FIELD = 10, // validate field(s) of an incomplete record
///
/// Validates a record that will be deleted later. You must first call MsiViewFetch. Fails if another row refers to the primary
/// keys of this row. Validation does not check for the existence of the primary keys of this row in properties or strings. Does
/// not check if a column is a foreign key to multiple tables. Obtain validation errors by calling MsiViewGetError. Works with
/// read-write and read-only records. This mode cannot be used with a view that contains joins.
///
MSIMODIFY_VALIDATE_DELETE = 11, // validate before deleting record
}
/// Specifies the run mode.
[PInvokeData("msiquery.h")]
public enum MSIRUNMODE
{
/// The administrative mode is installing, or the product is installing.
MSIRUNMODE_ADMIN = 0, // admin mode install, else product install
/// The advertisements are installing or the product is installing or updating.
MSIRUNMODE_ADVERTISE = 1, // installing advertisements, else installing or updating product
/// An existing installation is being modified or there is a new installation.
MSIRUNMODE_MAINTENANCE = 2, // modifying an existing installation, else new installation
/// Rollback is enabled.
MSIRUNMODE_ROLLBACKENABLED = 3, // rollback is enabled
/// The log file is active. It was enabled prior to the installation session.
MSIRUNMODE_LOGENABLED = 4, // log file active, enabled prior to install session
/// Execute operations are in the determination phase.
MSIRUNMODE_OPERATIONS = 5, // spooling execute operations, else in determination phase
/// A reboot is necessary after a successful installation (settable).
MSIRUNMODE_REBOOTATEND = 6, // reboot needed after successful installation (settable)
/// A reboot is necessary to continue the installation (settable).
MSIRUNMODE_REBOOTNOW = 7, // reboot needed to continue installation (settable)
/// Files from cabinets and Media table files are installing.
MSIRUNMODE_CABINET = 8, // installing files from cabinets and files using Media table
/// The source LongFileNames is suppressed through the PID_MSISOURCE summary property.
MSIRUNMODE_SOURCESHORTNAMES = 9, // source LongFileNames suppressed via PID_MSISOURCE summary property
/// The target LongFileNames is suppressed through the SHORTFILENAMES property.
MSIRUNMODE_TARGETSHORTNAMES = 10, // target LongFileNames suppressed via SHORTFILENAMES property
/// Reserved for future use.
MSIRUNMODE_RESERVED11 = 11, // future use
/// The operating system is a 9x version.
MSIRUNMODE_WINDOWS9X = 12, // operating systems is Windows9?, else Windows NT
/// The operating system supports demand installation.
MSIRUNMODE_ZAWENABLED = 13, // operating system supports demand installation
/// Reserved for future use.
MSIRUNMODE_RESERVED14 = 14, // future use
/// Reserved for future use.
MSIRUNMODE_RESERVED15 = 15, // future use
/// A custom action called from install script execution.
MSIRUNMODE_SCHEDULED = 16, // custom action call from install script execution
/// A custom action called from rollback execution script.
MSIRUNMODE_ROLLBACK = 17, // custom action call from rollback execution script
/// A custom action called from commit execution script.
MSIRUNMODE_COMMIT = 18, // custom action call from commit execution script
}
/// The error conditions that should be suppressed when the transform is applied.
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiCreateTransformSummaryInfoA")]
[Flags]
public enum MSITRANSFORM_ERROR
{
/// Adding a row that exists.
MSITRANSFORM_ERROR_ADDEXISTINGROW = 0x00000001,
/// Deleting a row that does not exist.
MSITRANSFORM_ERROR_DELMISSINGROW = 0x00000002,
/// Adding a table that exists.
MSITRANSFORM_ERROR_ADDEXISTINGTABLE = 0x00000004,
/// Deleting a table that does not exist.
MSITRANSFORM_ERROR_DELMISSINGTABLE = 0x00000008,
/// Updating a row that does not exist.
MSITRANSFORM_ERROR_UPDATEMISSINGROW = 0x00000010,
/// Transform and database code pages do not match, and their code pages are neutral.
MSITRANSFORM_ERROR_CHANGECODEPAGE = 0x00000020,
/// Create the temporary _TransformView table.
MSITRANSFORM_ERROR_VIEWTRANSFORM = 0x00000100,
}
// Note: INSTALLMESSAGE_ERROR, INSTALLMESSAGE_WARNING, INSTALLMESSAGE_USER are to or'd with a message box style to indicate the
// buttons to display and return: MB_OK,MB_OKCANCEL,MB_ABORTRETRYIGNORE,MB_YESNOCANCEL,MB_YESNO,MB_RETRYCANCEL the default button
// (MB_DEFBUTTON1 is normal default): MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON3 and optionally an icon style: MB_ICONERROR,
// MB_ICONQUESTION, MB_ICONWARNING, MB_ICONINFORMATION
/// Specifies the properties to be validated to verify that the transform can be applied to the database.
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiCreateTransformSummaryInfoA")]
[Flags]
public enum MSITRANSFORM_VALIDATE
{
/// Default language must match base database.
MSITRANSFORM_VALIDATE_LANGUAGE = 0x00000001,
/// Product must match base database.
MSITRANSFORM_VALIDATE_PRODUCT = 0x00000002,
///
MSITRANSFORM_VALIDATE_PLATFORM = 0x00000004,
/// Check major version only.
MSITRANSFORM_VALIDATE_MAJORVERSION = 0x00000008,
/// Check major and minor versions only.
MSITRANSFORM_VALIDATE_MINORVERSION = 0x00000010,
/// Check major, minor, and update versions.
MSITRANSFORM_VALIDATE_UPDATEVERSION = 0x00000020,
/// Installed version < base version.
MSITRANSFORM_VALIDATE_NEWLESSBASEVERSION = 0x00000040,
/// Installed version <= base version.
MSITRANSFORM_VALIDATE_NEWLESSEQUALBASEVERSION = 0x00000080,
/// Installed version = base version.
MSITRANSFORM_VALIDATE_NEWEQUALBASEVERSION = 0x00000100,
/// Installed version >= base version.
MSITRANSFORM_VALIDATE_NEWGREATEREQUALBASEVERSION = 0x00000200,
/// Installed version > base version.
MSITRANSFORM_VALIDATE_NEWGREATERBASEVERSION = 0x00000400,
/// UpgradeCode must match base database.
MSITRANSFORM_VALIDATE_UPGRADECODE = 0x00000800,
}
///
/// The MsiCreateRecord function creates a new record object with the specified number of fields. This function returns a
/// handle that should be closed using MsiCloseHandle.
///
///
/// Specifies the number of fields the record will have. The maximum number of fields in a record is limited to 65535.
///
///
/// If the function succeeds, the return value is handle to a new record object.
/// If the function fails, the return value is null.
///
///
///
/// Field 0 of the record object created by the MsiCreateRecord function is used for format strings and operation codes and
/// is not included in the count specified by cParams. All fields are initialized to null.
///
///
/// Note that it is recommended to use variables of type PMSIHANDLE because the installer closes PMSIHANDLE objects as they go out
/// of scope, whereas you must close MSIHANDLE objects by calling MsiCloseHandle. For more information see Use PMSIHANDLE instead of
/// HANDLE section in the Windows Installer Best Practices.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msicreaterecord MSIHANDLE MsiCreateRecord( UINT cParams );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiCreateRecord")]
public static extern PMSIHANDLE MsiCreateRecord(uint cParams);
///
/// The MsiCreateTransformSummaryInfo function creates summary information of an existing transform to include validation and
/// error conditions. Execution of this function sets the error record, which is accessible by using MsiGetLastErrorRecord.
///
/// The handle to the database that contains the new database summary information.
/// The handle to the database that contains the original summary information.
/// The name of the transform to which the summary information is added.
///
/// The error conditions that should be suppressed when the transform is applied. Use one or more of the following values.
///
///
/// Error condition
/// Meaning
///
/// -
/// none 0x00000000
/// None of the following conditions.
///
/// -
/// MSITRANSFORM_ERROR_ADDEXISTINGROW 0x00000001
/// Adding a row that exists.
///
/// -
/// MSITRANSFORM_ERROR_DELMISSINGROW 0x00000002
/// Deleting a row that does not exist.
///
/// -
/// MSITRANSFORM_ERROR_ADDEXISTINGTABLE 0x00000004
/// Adding a table that exists.
///
/// -
/// MSITRANSFORM_ERROR_DELMISSINGTABLE 0x00000008
/// Deleting a table that does not exist.
///
/// -
/// MSITRANSFORM_ERROR_UPDATEMISSINGROW 0x00000010
/// Updating a row that does not exist.
///
/// -
/// MSITRANSFORM_ERROR_CHANGECODEPAGE 0x00000020
/// Transform and database code pages do not match, and their code pages are neutral.
///
///
///
///
///
/// Specifies the properties to be validated to verify that the transform can be applied to the database. This parameter can be one
/// or more of the following values.
///
///
///
/// Validation flag
/// Meaning
///
/// -
/// none 0x00000000
/// Do not validate properties.
///
/// -
/// MSITRANSFORM_VALIDATE_LANGUAGE 0x00000001
/// Default language must match base database.
///
/// -
/// MSITRANSFORM_VALIDATE_PRODUCT 0x00000002
/// Product must match base database.
///
///
/// Validate product version flags.
///
///
/// Validation flag
/// Meaning
///
/// -
/// MSITRANSFORM_VALIDATE_MAJORVERSION 0x00000008
/// Check major version only.
///
/// -
/// MSITRANSFORM_VALIDATE_MINORVERSION 0x00000010
/// Check major and minor versions only.
///
/// -
/// MSITRANSFORM_VALIDATE_UPDATEVERSION 0x00000020
/// Check major, minor, and update versions.
///
///
///
/// Product version relationship flags. In the following table the installed version is the version of the package that is being
/// transformed, and the base version is the version of the package that is used to create the transform.
///
///
///
/// Validation flag
/// Meaning
///
/// -
/// MSITRANSFORM_VALIDATE_NEWLESSBASEVERSION 0x00000040
/// Installed version < base version.
///
/// -
/// MSITRANSFORM_VALIDATE_NEWLESSEQUALBASEVERSION 0x00000080
/// Installed version <= base version.
///
/// -
/// MSITRANSFORM_VALIDATE_NEWEQUALBASEVERSION 0x00000100
/// Installed version = base version.
///
/// -
/// MSITRANSFORM_VALIDATE_NEWGREATEREQUALBASEVERSION 0x00000200
/// Installed version >= base version.
///
/// -
/// MSITRANSFORM_VALIDATE_NEWGREATERBASEVERSION 0x00000400
/// Installed version > base version.
///
///
/// Upgrade code validation flags.
///
///
/// Validation flag
/// Meaning
///
/// -
/// MSITRANSFORM_VALIDATE_UPGRADECODE 0x00000800
/// UpgradeCode must match base database.
///
///
///
/// This function returns UINT.
///
///
/// The ProductCode Property and ProductVersion Property must be defined in the Property Table of both the base and reference
/// databases. If MSITRANSFORM_VALIDATE_UPGRADECODE is used, the UpgradeCode Property must also be defined in both databases. If
/// these conditions are not met, MsiCreateTransformSummaryInfo returns ERROR_INSTALL_PACKAGE_INVALID.
///
///
/// -
/// Do not use the semicolon for filenames or paths, because it is used as a list delimiter for transforms, sources, and patches.
///
/// -
///
/// This function cannot be called from custom actions. A call to this function from a custom action causes the function to fail.
///
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msicreatetransformsummaryinfoa UINT
// MsiCreateTransformSummaryInfoA( MSIHANDLE hDatabase, MSIHANDLE hDatabaseReference, LPCSTR szTransformFile, int iErrorConditions,
// int iValidation );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiCreateTransformSummaryInfoA")]
public static extern Win32Error MsiCreateTransformSummaryInfo(MSIHANDLE hDatabase, MSIHANDLE hDatabaseReference, [MarshalAs(UnmanagedType.LPTStr)] string szTransformFile,
MSITRANSFORM_ERROR iErrorConditions, MSITRANSFORM_VALIDATE iValidation);
/// The MsiDatabaseApplyTransform function applies a transform to a database.
/// Handle to the database obtained from MsiOpenDatabase to the transform.
/// Specifies the name of the transform file to apply.
///
/// Error conditions that should be suppressed. This parameter is a bit field that can contain the following bits.
///
///
/// Error condition
/// Meaning
///
/// -
/// MSITRANSFORM_ERROR_ADDEXISTINGROW 0x0001
/// Adding a row that already exists.
///
/// -
/// MSITRANSFORM_ERROR_DELMISSINGROW 0x0002
/// Deleting a row that does not exist.
///
/// -
/// MSITRANSFORM_ERROR_ADDEXISTINGTABLE 0x0004
/// Adding a table that already exists.
///
/// -
/// MSITRANSFORM_ERROR_DELMISSINGTABLE 0x0008
/// Deleting a table that does not exist.
///
/// -
/// MSITRANSFORM_ERROR_UPDATEMISSINGROW 0x0010
/// Updating a row that does not exist.
///
/// -
/// MSITRANSFORM_ERROR_CHANGECODEPAGE 0x0020
/// Transform and database code pages do not match and neither has a neutral code page.
///
/// -
/// MSITRANSFORM_ERROR_VIEWTRANSFORM 0x0100
/// Create the temporary _TransformView table.
///
///
///
/// The MsiDatabaseApplyTransform function returns one of the following values:
///
///
/// The MsiDatabaseApplyTransform function delays transforming tables until it is necessary. Any tables to be added or
/// dropped are processed immediately. However, changes to the existing table are delayed until the table is loaded or the database
/// is committed.
///
/// An error occurs if MsiDatabaseApplyTransform is called when tables have already been loaded and saved to storage.
///
/// Because the list delimiter for transforms, sources and patches is a semicolon, this character should not be used for filenames
/// or paths.
///
///
/// This function cannot be called from custom actions. A call to this function from a custom action causes the function to fail.
///
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msidatabaseapplytransforma UINT
// MsiDatabaseApplyTransformA( MSIHANDLE hDatabase, LPCSTR szTransformFile, int iErrorConditions );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiDatabaseApplyTransformA")]
public static extern Win32Error MsiDatabaseApplyTransform(MSIHANDLE hDatabase, [MarshalAs(UnmanagedType.LPTStr)] string szTransformFile, MSITRANSFORM_ERROR iErrorConditions);
/// The MsiDatabaseCommit function commits changes to a database.
/// Handle to the database obtained from MsiOpenDatabase.
/// The MsiDatabaseCommit function returns one of the following values:
///
///
/// The MsiDatabaseCommit function finalizes the persistent form of the database. All persistent data is then written to the
/// writable database. No temporary columns or rows are written. The MsiDatabaseCommit function has no effect on a database
/// that is opened as read-only. You can call this function multiple times to save the current state of tables loaded into memory.
/// When the database is finally closed, any changes made after the database is committed are rolled back. This function is normally
/// called prior to shutdown when all database changes have been finalized.
///
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msidatabasecommit UINT MsiDatabaseCommit( MSIHANDLE
// hDatabase );
[DllImport(Lib_Msi, SetLastError = true, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiDatabaseCommit")]
public static extern Win32Error MsiDatabaseCommit(MSIHANDLE hDatabase);
///
/// The MsiDatabaseExport function exports a Microsoft Installer table from an open database to a Text Archive File.
///
/// The handle to a database from MsiOpenDatabase.
/// The name of the table to export.
/// The name of the folder that contains archive files.
/// The name of the exported table archive file.
///
/// The MsiDatabaseExport function returns one of the following values:
///
///
/// Return code
/// Description
///
/// -
/// ERROR_BAD_PATHNAME
/// An invalid path is passed to the function.
///
/// -
/// ERROR_FUNCTION_FAILED
/// The function fails.
///
/// -
/// ERROR_INVALID_HANDLE
/// An invalid or inactive handle is supplied.
///
/// -
/// ERROR_INVALID_PARAMETER
/// An invalid parameter is passed to the function.
///
/// -
/// ERROR_SUCCESS
/// The function succeeds.
///
///
///
///
/// If a table contains streams, MsiDatabaseExport exports each stream to a separate file.
/// For more information, see MsiDatabaseImport.
///
/// This function cannot be called from custom actions. A call to this function from a custom action causes the function to fail.
///
/// If the function fails, you can get extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msidatabaseexporta UINT MsiDatabaseExportA( MSIHANDLE
// hDatabase, LPCSTR szTableName, LPCSTR szFolderPath, LPCSTR szFileName );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiDatabaseExportA")]
public static extern Win32Error MsiDatabaseExport(MSIHANDLE hDatabase, [MarshalAs(UnmanagedType.LPTStr)] string szTableName,
[MarshalAs(UnmanagedType.LPTStr)] string szFolderPath, [MarshalAs(UnmanagedType.LPTStr)] string szFileName);
///
/// The MsiDatabaseGenerateTransform function generates a transform file of differences between two databases. A transform is
/// a way of recording changes to a database without altering the original database. You can also use
/// MsiDatabaseGenerateTransform to test whether two databases are identical without creating a transform.
///
/// Handle to the database obtained from MsiOpenDatabase that includes the changes.
/// Handle to the database obtained from MsiOpenDatabase that does not include the changes.
///
/// A null-terminated string that specifies the name of the transform file being generated. This parameter can be null. If
/// szTransformFile is null, you can use MsiDatabaseGenerateTransform to test whether two databases are identical without
/// creating a transform. If the databases are identical, the function returns ERROR_NO_DATA. If the databases are different the
/// function returns NOERROR.
///
/// This is a reserved argument and must be set to 0.
/// This is a reserved argument and must be set to 0.
/// The MsiDatabaseGenerateTransform function returns one of the following values:
///
///
/// To generate a difference file between two databases, use the MsiDatabaseGenerateTransform function. A transform contains
/// information regarding insertion and deletion of columns and rows. The validation flags are stored in the summary information
/// stream of the transform file.
///
///
/// For tables that exist in both databases, the only difference between the two schemas that is allowed is the addition of columns
/// to the end of the reference table. You cannot add primary key columns to a table or change the order or names or column
/// definitions of the existing columns as defined in the base table. In other words, if neither table contains data and columns are
/// removed from the reference table, the resulting table is identical to the base table.
///
///
/// Because the list delimiter for transforms, sources and patches is a semicolon, this character should not be used for filenames
/// or paths.
///
///
/// This function does not generate a Summary Information stream. Use MsiCreateTransformSummaryInfo to create the stream for an
/// existing transform.
///
///
/// If szTransformFile is null, you can test whether two databases are identical without creating a transform. If the databases are
/// identical, ERROR_NO_DATA is returned, NOERROR is returned if differences are found.
///
///
/// This function cannot be called from custom actions. A call to this function from a custom action causes the function to fail.
///
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msidatabasegeneratetransforma UINT
// MsiDatabaseGenerateTransformA( MSIHANDLE hDatabase, MSIHANDLE hDatabaseReference, LPCSTR szTransformFile, int iReserved1, int
// iReserved2 );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiDatabaseGenerateTransformA")]
public static extern Win32Error MsiDatabaseGenerateTransform(MSIHANDLE hDatabase, MSIHANDLE hDatabaseReference, [Optional, MarshalAs(UnmanagedType.LPTStr)] string szTransformFile,
int iReserved1 = 0, int iReserved2 = 0);
///
/// The MsiDatabaseGetPrimaryKeys function returns a record containing the names of all the primary key columns for a
/// specified table. This function returns a handle that should be closed using MsiCloseHandle.
///
/// Handle to the database. See Obtaining a Database Handle.
/// Specifies the name of the table from which to obtain primary key names.
/// Pointer to the handle of the record that holds the primary key names.
/// This function returns UINT.
///
///
/// The field count of the returned record is the count of primary key columns returned by the MsiDatabaseGetPrimaryKeys
/// function. The returned record contains the table name in Field (0) and the column names that make up the primary key names in
/// succeeding fields. These primary key names correspond to the column numbers for the fields.
///
/// This function cannot be used with the _Tables table or the _Columns table.
///
/// Note that it is recommended to use variables of type PMSIHANDLE because the installer closes PMSIHANDLE objects as they go out
/// of scope, whereas you must close MSIHANDLE objects by calling MsiCloseHandle. For more information see Use PMSIHANDLE instead of
/// HANDLE section in the Windows Installer Best Practices.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msidatabasegetprimarykeysa UINT
// MsiDatabaseGetPrimaryKeysA( MSIHANDLE hDatabase, LPCSTR szTableName, MSIHANDLE *phRecord );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiDatabaseGetPrimaryKeysA")]
public static extern Win32Error MsiDatabaseGetPrimaryKeys(MSIHANDLE hDatabase, [MarshalAs(UnmanagedType.LPTStr)] string szTableName, out PMSIHANDLE phRecord);
/// The MsiDatabaseImport function imports an installer text archive file into an open database table.
/// Handle to the database obtained from MsiOpenDatabase.
/// Specifies the path to the folder that contains archive files.
/// Specifies the name of the file to import.
/// The MsiDatabaseImport function returns one of the following values:
///
///
/// When you use the MsiDatabaseImport function to import a text archive table named _SummaryInformation into an installer
/// database, you write the "05SummaryInformation" stream. This stream contains standard properties that can be viewed using Windows
/// Explorer and are defined by COM. The rows of the table are written to the property stream as pairs of property ID numbers and
/// corresponding data values. See Summary Information Stream Property Set. Date and time in _SummaryInformation are in the format:
/// YYYY/MM/DD hh::mm::ss. For example, 1999/03/22 15:25:45. If the table contains binary streams, the name of the stream is in the
/// data field, and the actual stream is retrieved from a file of that name in a subfolder with the same name as the table.
///
///
/// Text archive files that are exported from a database by MsiDatabaseExport are intended for use with version control systems, and
/// are not intended to be used as a means of editing data. Use the database API functions and tools designed for that purpose. Note
/// that control characters in text archive files are translated to avoid conflicts with file delimiters. If a text archive file
/// contains non-ASCII data, it is stamped with the code page of the data, and can only be imported into a database of that exact
/// code page, or into a neutral database. Neutral databases are set to the code page of the imported file. A database can be
/// unconditionally set to a particular code page by importing a pseudo table named: _ForceCodepage. The format of such a file is:
/// Two blank lines, followed by a line that contains the numeric code page, a tab delimiter and the exact string: _ForceCodepage
///
///
/// This function cannot be called from custom actions. A call to this function from a custom action causes the function to fail.
///
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msidatabaseimporta UINT MsiDatabaseImportA( MSIHANDLE
// hDatabase, LPCSTR szFolderPath, LPCSTR szFileName );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiDatabaseImportA")]
public static extern Win32Error MsiDatabaseImport(MSIHANDLE hDatabase, [MarshalAs(UnmanagedType.LPTStr)] string szFolderPath,
[MarshalAs(UnmanagedType.LPTStr)] string szFileName);
/// The MsiDatabaseIsTablePersistent function returns an enumeration that describes the state of a specific table.
///
/// Handle to the database that belongs to the relevant table. For more information, see Obtaining a Database Handle.
///
/// Specifies the name of the relevant table.
/// This function returns MSICONDITION.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msidatabaseistablepersistenta MSICONDITION
// MsiDatabaseIsTablePersistentA( MSIHANDLE hDatabase, LPCSTR szTableName );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiDatabaseIsTablePersistentA")]
public static extern MSICONDITION MsiDatabaseIsTablePersistent(MSIHANDLE hDatabase, [MarshalAs(UnmanagedType.LPTStr)] string szTableName);
/// The MsiDatabaseMerge function merges two databases together, which allows duplicate rows.
/// The handle to the database obtained from MsiOpenDatabase.
/// The handle to the database obtained from MsiOpenDatabase to merge into the base database.
/// The name of the table to receive merge conflict information.
///
/// The MsiDatabaseMerge function returns one of the following values:
///
///
/// Return code
/// Description
///
/// -
/// ERROR_FUNCTION_FAILED
/// Row merge conflicts were reported.
///
/// -
/// ERROR_INVALID_HANDLE
/// An invalid or inactive handle was supplied.
///
/// -
/// ERROR_INVALID_TABLE
/// An invalid table was supplied.
///
/// -
/// ERROR_SUCCESS
/// The function succeeded.
///
/// -
/// ERROR_DATATYPE_MISMATCH
/// Schema difference between the two databases.
///
///
///
///
///
/// The MsiDatabaseMerge function and the Merge method of the Database object cannot be used to merge a module that is
/// included in the installation package. They should not be used to merge Merge Modules into a Windows Installer package. To
/// include a merge module in an installation package, authors of installation packages should follow the guidelines that are
/// described in the Applying Merge Modules topic.
///
///
/// MsiDatabaseMerge does not copy over embedded Cabinet Files or embedded transforms from the reference database into the
/// target database. Embedded data streams that are listed in the Binary Table or Icon Table are copied from the reference database
/// to the target database. Storage embedded in the reference database are not copied to the target database.
///
///
/// The MsiDatabaseMerge function merges the data of two databases. These databases must have the same code page.
/// MsiDatabaseMerge fails if any tables or rows in the databases conflict. A conflict exists if the data in any row in the
/// first database differs from the data in the corresponding row of the second database. Corresponding rows are in the same table
/// of both databases and have the same primary key in both databases. The tables of non-conflicting databases must have the same
/// number of primary keys, same number of columns, same column types, same column names, and the same data in rows with identical
/// primary keys. Temporary columns however don't matter in the column count and corresponding tables can have a different number of
/// temporary columns without creating conflict as long as the persistent columns match.
///
///
/// If the number, type, or name of columns in corresponding tables are different, the schema of the two databases are incompatible
/// and the installer stops processing tables and the merge fails. The installer checks that the two databases have the same schema
/// before checking for row merge conflicts. If ERROR_DATATYPE_MISMATCH is returned, you are guaranteed that the databases have not
/// been changed.
///
///
/// If the data in particular rows differ, this is a row merge conflict, the installer returns ERROR_FUNCTION_FAILED and creates a
/// new table named szTableName. The first column of this table is the name of the table having the conflict. The second column
/// gives the number of rows in the table having the conflict. The table that reports conflicts appears as follows.
///
///
///
/// Column
/// Type
/// Key
/// Nullable
///
/// -
/// Table
/// Text
/// Y
/// N
///
/// -
/// NumRowMergeConflicts
/// Integer
///
/// N
///
///
///
/// This function cannot be called from custom actions. A call to this function from a custom action causes the function to fail.
///
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msidatabasemergea UINT MsiDatabaseMergeA( MSIHANDLE
// hDatabase, MSIHANDLE hDatabaseMerge, LPCSTR szTableName );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiDatabaseMergeA")]
public static extern Win32Error MsiDatabaseMerge(MSIHANDLE hDatabase, MSIHANDLE hDatabaseMerge, [MarshalAs(UnmanagedType.LPTStr)] string szTableName);
///
/// The MsiDatabaseOpenView function prepares a database query and creates a view object. This function returns a handle that
/// should be closed using MsiCloseHandle.
///
///
/// Handle to the database to which you want to open a view object. You can get the handle as described in Obtaining a Database Handle.
///
/// Specifies a SQL query string for querying the database. For correct syntax, see SQL Syntax.
/// Pointer to a handle for the returned view.
/// The MsiDatabaseOpenView function returns one of the following values:
///
///
/// The MsiDatabaseOpenView function opens a view object for a database. You must open a view object for a database before
/// performing any execution or fetching.
///
/// If an error occurs, you can call MsiGetLastErrorRecord for more information.
///
/// Note that it is recommended to use variables of type PMSIHANDLE because the installer closes PMSIHANDLE objects as they go out
/// of scope, whereas you must close MSIHANDLE objects by calling MsiCloseHandle. For more information see Use PMSIHANDLE instead of
/// HANDLE section in the Windows Installer Best Practices.
///
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msidatabaseopenviewa UINT MsiDatabaseOpenViewA( MSIHANDLE
// hDatabase, LPCSTR szQuery, MSIHANDLE *phView );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiDatabaseOpenViewA")]
public static extern Win32Error MsiDatabaseOpenView(MSIHANDLE hDatabase, [MarshalAs(UnmanagedType.LPTStr)] string szQuery, out PMSIHANDLE phView);
/// The MsiDoAction function executes a built-in action, custom action, or user-interface wizard action.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
/// Specifies the action to execute.
/// This function returns UINT.
///
///
/// The MsiDoAction function executes the action that corresponds to the name supplied. If the name is not recognized by the
/// installer as a built-in action or as a custom action in the CustomAction table, the name is passed to the user-interface handler
/// object, which can invoke a function or a dialog box. If a null action name is supplied, the installer uses the upper-case value
/// of the ACTION property as the action to perform. If no property value is defined, the default action is performed, defined as "INSTALL".
///
///
/// Actions that update the system, such as the InstallFiles and WriteRegistryValues actions, cannot be run by calling
/// MsiDoAction. The exception to this rule is if MsiDoAction is called from a custom action that is scheduled in the
/// InstallExecuteSequence table between the InstallInitialize and InstallFinalize actions. Actions that do not update the system,
/// such as AppSearch or CostInitialize, can be called.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msidoactiona UINT MsiDoActionA( MSIHANDLE hInstall,
// LPCSTR szAction );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiDoActionA")]
public static extern Win32Error MsiDoAction(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szAction);
///
/// The MsiEnableUIPreview function enables preview mode of the user interface to facilitate authoring of user-interface
/// dialog boxes. This function returns a handle that should be closed using MsiCloseHandle.
///
/// Handle to the database.
/// Pointer to a returned handle for user-interface preview capability.
/// This function returns UINT.
///
/// Note that it is recommended to use variables of type PMSIHANDLE because the installer closes PMSIHANDLE objects as they go out
/// of scope, whereas you must close MSIHANDLE objects by calling MsiCloseHandle. For more information see Use PMSIHANDLE instead of
/// HANDLE section in the Windows Installer Best Practices.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msienableuipreview UINT MsiEnableUIPreview( MSIHANDLE
// hDatabase, MSIHANDLE *phPreview );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiEnableUIPreview")]
public static extern Win32Error MsiEnableUIPreview(MSIHANDLE hDatabase, out PMSIHANDLE phPreview);
///
///
/// The MsiEnumComponentCosts function enumerates the disk-space per drive required to install a component. This information
/// is needed to display the disk-space cost required for all drives in the user interface. The returned disk-space costs are
/// expressed in multiples of 512 bytes.
///
///
/// MsiEnumComponentCosts should only be run after the installer has completed file costing and after the CostFinalize
/// action. For more information, see File Costing.
///
///
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
///
/// A null-terminated string specifying the component's name as it is listed in the Component column of the Component table. This
/// parameter can be null. If szComponent is null or an empty string, MsiEnumComponentCosts enumerates the total disk-space
/// per drive used during the installation. In this case, iState is ignored. The costs of the installer include those costs for
/// caching the database in the secure folder as well as the cost to create the installation script. Note that the total disk-space
/// used during the installation may be larger than the space used after the component is installed.
///
///
/// 0-based index for drives. This parameter should be zero for the first call to the MsiEnumComponentCosts function and then
/// incremented for subsequent calls.
///
///
/// Requested component state to be enumerated. If szComponent is passed as Null or an empty string, the installer ignores the
/// iState parameter.
///
///
/// Buffer that holds the drive name including the null terminator. This is an empty string in case of an error.
///
///
/// Pointer to a variable that specifies the size, in TCHARs, of the buffer pointed to by the lpDriveBuf parameter. This size should
/// include the terminating null character. If the buffer provided is too small, the variable pointed to by pcchDriveBuf contains
/// the count of characters not including the null terminator.
///
///
/// Cost of the component per drive expressed in multiples of 512 bytes. This value is 0 if an error has occurred. The value
/// returned in piCost is final disk-space used by the component after installation. If szComponent is passed as Null or an empty
/// string, the installer sets the value at piCost to 0.
///
///
/// The component cost per drive for the duration of the installation, or 0 if an error occurred. The value in *piTempCost
/// represents the temporary space requirements for the duration of the installation. This temporary space requirement is space
/// needed only for the duration of the installation. This does not affect the final disk space requirement.
///
///
///
///
/// Return Value
/// Meaning
///
/// -
/// ERROR_INVALID_HANDLE_STATE
/// The configuration data is corrupt.
///
/// -
/// ERROR_INVALID_PARAMETER
/// An invalid parameter was passed to the function.
///
/// -
/// ERROR_NO_MORE_ITEMS
/// There are no more drives to return.
///
/// -
/// ERROR_SUCCESS
/// A value was enumerated.
///
/// -
/// ERROR_UNKNOWN_COMPONENT
/// The component is missing.
///
/// -
/// ERROR_FUNCTION_NOT_CALLED
/// Costing is not complete.
///
/// -
/// ERROR_MORE_DATA
/// Buffer not large enough for the drive name.
///
/// -
/// ERROR_INVALID_HANDLE
/// The supplied handle is invalid or inactive.
///
///
///
///
///
/// The recommended method for enumerating the disk-space costs per drive is as follows. Start with the dwIndex set to 0 and
/// increment it by one after each call. Continue the enumeration as long as MsiEnumComponentCosts returns ERROR_SUCCESS.
///
/// MsiEnumComponentCosts may be called from custom actions.
///
/// The total final disk cost for the installation is the sum of the costs of all components plus the cost of the Windows Installer
/// (szComponent = null).
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msienumcomponentcostsa UINT MsiEnumComponentCostsA(
// MSIHANDLE hInstall, LPCSTR szComponent, DWORD dwIndex, INSTALLSTATE iState, LPSTR szDriveBuf, LPDWORD pcchDriveBuf, LPINT piCost,
// LPINT piTempCost );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiEnumComponentCostsA")]
public static extern Win32Error MsiEnumComponentCosts(MSIHANDLE hInstall, [Optional, MarshalAs(UnmanagedType.LPTStr)] string szComponent, uint dwIndex,
INSTALLSTATE iState, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder szDriveBuf, ref uint pcchDriveBuf, out int piCost, out int piTempCost);
/// The MsiEvaluateCondition function evaluates a conditional expression containing property names and values.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
///
/// Specifies the conditional expression. This parameter must not be NULL. For the syntax of conditional expressions see
/// Conditional Statement Syntax.
///
/// This function returns MSICONDITION.
///
///
/// The following table shows the feature and component state values used by the MsiEvaluateCondition function. These states
/// are not set until MsiSetInstallLevel is called, either directly or by the CostFinalize action. Therefore, state checking is
/// generally only useful for conditional expressions in an action sequence table.
///
///
///
/// Value
/// Meaning
///
/// -
/// INSTALLSTATE_ABSENT
/// Feature or component not present.
///
/// -
/// INSTALLSTATE_LOCAL
/// Feature or component on local computer.
///
/// -
/// INSTALLSTATE_SOURCE
/// Feature or component run from source.
///
/// -
/// (null value)
/// No action to be taken on feature or component.
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msievaluateconditiona MSICONDITION MsiEvaluateConditionA(
// MSIHANDLE hInstall, LPCSTR szCondition );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiEvaluateConditionA")]
public static extern MSICONDITION MsiEvaluateCondition(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szCondition);
/// The MsiFormatRecord function formats record field data and properties using a format string.
///
/// Handle to the installation. This may be omitted, in which case only the record field parameters are processed and properties are
/// not available for substitution.
///
///
/// Handle to the record to format. The template string must be stored in record field 0 followed by referenced data parameters.
///
///
/// Pointer to the buffer that receives the null terminated formatted string. Do not attempt to determine the size of the buffer by
/// passing in a null (value=0) for szResultBuf. You can get the size of the buffer by passing in an empty string (for example "").
/// The function then returns ERROR_MORE_DATA and pcchResultBuf contains the required buffer size in TCHAR s, not
/// including the terminating null character. On return of ERROR_SUCCESS, pcchResultBuf contains the number of TCHAR s
/// written to the buffer, not including the terminating null character.
///
///
/// Pointer to the variable that specifies the size, in TCHAR s, of the buffer pointed to by the variable szResultBuf. When
/// the function returns ERROR_SUCCESS, this variable contains the size of the data copied to szResultBuf, not including the
/// terminating null character. If szResultBuf is not large enough, the function returns ERROR_MORE_DATA and stores the
/// required size, not including the terminating null character, in the variable pointed to by pcchResultBuf.
///
/// The MsiFormatRecord function returns one of the following values:
///
/// The MsiFormatRecord function uses the following format process.
///
/// Parameters that are to be formatted are enclosed in square brackets [...]. The square brackets can be iterated because the
/// substitutions are resolved from the inside out.
///
///
/// If a part of the string is enclosed in curly braces { } and contains no square brackets, it is left unchanged, including the
/// curly braces.
///
///
/// If a part of the string is enclosed in curly braces { } and contains one or more property names, and if all the properties are
/// found, the text (with the resolved substitutions) is displayed without the curly braces. If any of the properties is not found,
/// all the text in the braces and the braces themselves are removed.
///
///
/// Note in the case of deferred execution custom actions, MsiFormatRecord only supports CustomActionData and
/// ProductCode properties. For more information, see Obtaining Context Information for Deferred Execution Custom Actions.
///
/// The following steps describe how to format strings using the MsiFormatRecord function:
/// To format strings using the MsiFormatRecord function
///
/// -
///
/// The numeric parameters are substituted by replacing the marker with the value of the corresponding record field, with missing or
/// null values producing no text.
///
///
/// -
/// The resultant string is processed by replacing the nonrecord parameters with the corresponding values, described next.
///
///
///
/// If ERROR_MORE_DATA is returned, the parameter which is a pointer gives the size of the buffer required to hold the
/// string. If ERROR_SUCCESS is returned, it gives the number of characters written to the string buffer. Therefore you can
/// get the size of the buffer by passing in an empty string (for example "") for the parameter that specifies the buffer. Do not
/// attempt to determine the size of the buffer by passing in a Null (value=0).
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msiformatrecorda UINT MsiFormatRecordA( MSIHANDLE
// hInstall, MSIHANDLE hRecord, LPSTR szResultBuf, LPDWORD pcchResultBuf );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiFormatRecordA")]
public static extern Win32Error MsiFormatRecord([Optional] MSIHANDLE hInstall, MSIHANDLE hRecord,
[MarshalAs(UnmanagedType.LPTStr)] StringBuilder szResultBuf, ref uint pcchResultBuf);
///
/// The MsiGetActiveDatabase function returns the active database for the installation. This function returns a read-only
/// handle that should be closed using MsiCloseHandle.
///
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
///
/// If the function succeeds, it returns a read-only handle to the database currently in use by the installer. If the function
/// fails, the function returns zero, 0.
///
///
/// The MsiGetActiveDatabase function accesses the database in use by the running the installation.
///
/// Note that it is recommended to use variables of type PMSIHANDLE because the installer closes PMSIHANDLE objects as they go out
/// of scope, whereas you must close MSIHANDLE objects by calling MsiCloseHandle. For more information see Use PMSIHANDLE instead of
/// HANDLE section in the Windows Installer Best Practices.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msigetactivedatabase MSIHANDLE MsiGetActiveDatabase(
// MSIHANDLE hInstall );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiGetActiveDatabase")]
public static extern PMSIHANDLE MsiGetActiveDatabase(MSIHANDLE hInstall);
/// The MsiGetComponentState function obtains the state of a component.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
/// A null-terminated string that specifies the component name within the product.
///
/// Receives the current installed state. This parameter must not be null. This parameter can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// INSTALLSTATE_ABSENT
/// The component is not installed.
///
/// -
/// INSTALLSTATE_DEFAULT
/// The component is installed in the default location: local or source.
///
/// -
/// INSTALLSTATE_LOCAL
/// The component is installed on the local drive.
///
/// -
/// INSTALLSTATE_REMOVED
/// The component is being removed. In action state and not settable.
///
/// -
/// INSTALLSTATE_SOURCE
/// The component runs from the source, CD-ROM, or network.
///
/// -
/// INSTALLSTATE_UNKNOWN
/// An unrecognized product or feature name was passed to the function.
///
///
///
///
/// Receives the action taken during the installation. This parameter must not be null. For return values, see piInstalled.
///
/// The MsiGetComponentState function returns the following values:
///
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
/// For more information, see Calling Database Functions From Programs.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msigetcomponentstatea UINT MsiGetComponentStateA(
// MSIHANDLE hInstall, LPCSTR szComponent, INSTALLSTATE *piInstalled, INSTALLSTATE *piAction );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiGetComponentStateA")]
public static extern Win32Error MsiGetComponentState(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szComponent,
out INSTALLSTATE piInstalled, out INSTALLSTATE piAction);
/// The MsiGetDatabaseState function returns the state of the database.
/// Handle to the database obtained from MsiOpenDatabase.
/// This function returns MSIDBSTATE.
/// The MsiGetDatabaseState function returns the update state of the database.
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msigetdatabasestate MSIDBSTATE MsiGetDatabaseState(
// MSIHANDLE hDatabase );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiGetDatabaseState")]
public static extern MSIDBSTATE MsiGetDatabaseState(MSIHANDLE hDatabase);
///
/// The MsiGetFeatureCost function returns the disk space required by a feature and its selected children and parent features.
///
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
/// Specifies the name of the feature.
///
///
/// Specifies the value the function uses to determine disk space requirements. This parameter can be one of the following values.
///
///
///
/// Value
/// Meaning
///
/// -
/// MSICOSTTREE_CHILDREN
/// The children of the indicated feature are included in the cost.
///
/// -
/// MSICOSTTREE_PARENTS
/// The parent features of the indicated feature are included in the cost.
///
/// -
/// MSICOSTTREE_SELFONLY
/// The feature only is included in the cost.
///
///
///
///
/// Specifies the installation state. This parameter can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// INSTALLSTATE_UNKNOWN
/// The product or feature is unrecognized.
///
/// -
/// INSTALLSTATE_ABSENT
/// The product or feature is uninstalled.
///
/// -
/// INSTALLSTATE_LOCAL
/// The product or feature is installed on the local drive.
///
/// -
/// INSTALLSTATE_SOURCE
/// The product or feature is installed to run from source, CD, or network.
///
/// -
/// INSTALLSTATE_DEFAULT
/// The product or feature will be installed to use the default location: local or source.
///
///
///
/// Receives the disk space requirements in units of 512 bytes. This parameter must not be null.
/// The MsiGetFeatureCost function returns the following values:
///
/// See Calling Database Functions From Programs.
///
/// With the MsiGetFeatureCost function, the MSICOSTTREE_SELFONLY value indicates the total amount of disk space (in units of
/// 512 bytes) required by the specified feature only. This returned value does not include the children or the parent features of
/// the specified feature. This total cost is made up of the disk costs attributed to every component linked to the feature.
///
///
/// The MSICOSTTREE_CHILDREN value indicates the total amount of disk space (in units of 512 bytes) required by the specified
/// feature and its children. For each feature, the total cost is made up of the disk costs attributed to every component linked to
/// the feature.
///
///
/// The MSICOSTTREE_PARENTS value indicates the total amount of disk space (in units of 512 bytes) required by the specified feature
/// and its parent features (up to the root of the Feature table). For each feature, the total cost is made up of the disk costs
/// attributed to every component linked to the feature.
///
///
/// MsiGetFeatureCost is dependent upon several other functions to be successful. The following example demonstrates the
/// order in which these functions must be called:
///
///
/// MSIHANDLE hInstall; //product handle, must be closed int iCost; //cost returned by MsiGetFeatureCost MsiOpenPackage("Path to package....",&hInstall); //"Path to package...." should be replaced with the full path to the package to be opened MsiDoAction(hInstall,"CostInitialize"); // MsiDoAction(hInstall,"FileCost"); MsiDoAction(hInstall,"CostFinalize"); MsiDoAction(hInstall,"InstallValidate"); MsiGetFeatureCost(hInstall,"FeatureName",MSICOSTTREE_SELFONLY,INSTALLSTATE_ABSENT,&iCost); MsiCloseHandle(hInstall); //close the open product handle
///
/// The process to query the cost of features scheduled to be removed is slightly different:
///
/// MSIHANDLE hInstall; //product handle, must be closed int iCost; //cost returned by MsiGetFeatureCost MsiOpenPackage("Path to package....",&hInstall); //"Path to package...." should be replaced with the full path to the package to be opened MsiDoAction(hInstall,"CostInitialize"); // MsiDoAction(hInstall,"FileCost"); MsiDoAction(hInstall,"CostFinalize"); MsiSetFeatureState(hInstall,"FeatureName",INSTALLSTATE_ABSENT); //set the feature's state to "not installed" MsiDoAction(hInstall,"InstallValidate"); MsiGetFeatureCost(hInstall,"FeatureName",MSICOSTTREE_SELFONLY,INSTALLSTATE_ABSENT,&iCost); MsiCloseHandle(hInstall); //close the open product handle
///
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msigetfeaturecosta UINT MsiGetFeatureCostA( MSIHANDLE
// hInstall, LPCSTR szFeature, MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiGetFeatureCostA")]
public static extern Win32Error MsiGetFeatureCost(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szFeature, MSICOSTTREE iCostTree,
INSTALLSTATE iState, out int piCost);
/// The MsiGetFeatureState function gets the requested state of a feature.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
/// Specifies the feature name within the product.
///
///
/// Specifies the returned current installed state. This parameter must not be null. This parameter can be one of the following values.
///
///
///
/// Value
/// Meaning
///
/// -
/// INSTALLSTATE_BADCONFIG
/// The configuration data is corrupt.
///
/// -
/// INSTALLSTATE_INCOMPLETE
/// The installation is suspended or in progress.
///
/// -
/// INSTALLSTATE_SOURCEABSENT
/// The feature must run from the source, and the source is unavailable.
///
/// -
/// INSTALLSTATE_MOREDATA
/// The return buffer is full.
///
/// -
/// INSTALLSTATE_INVALIDARG
/// An invalid parameter was passed to the function.
///
/// -
/// INSTALLSTATE_UNKNOWN
/// An unrecognized product or feature was specified.
///
/// -
/// INSTALLSTATE_BROKEN
/// The feature is broken.
///
/// -
/// INSTALLSTATE_ADVERTISED
/// The advertised feature.
///
/// -
/// INSTALLSTATE_ABSENT
/// The feature was uninstalled.
///
/// -
/// INSTALLSTATE_LOCAL
/// The feature was installed on the local drive.
///
/// -
/// INSTALLSTATE_SOURCE
/// The feature must run from the source, CD-ROM, or network.
///
/// -
/// INSTALLSTATE_DEFAULT
/// The feature is installed in the default location: local or source.
///
///
///
///
/// Receives the action taken during the installation session. This parameter must not be null. For return values, see piInstalled.
///
/// The MsiGetFeatureState function returns the following values:
///
/// See Calling Database Functions From Programs.
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msigetfeaturestatea UINT MsiGetFeatureStateA( MSIHANDLE
// hInstall, LPCSTR szFeature, INSTALLSTATE *piInstalled, INSTALLSTATE *piAction );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiGetFeatureStateA")]
public static extern Win32Error MsiGetFeatureState(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szFeature,
out INSTALLSTATE piInstalled, out INSTALLSTATE piAction);
/// The MsiGetFeatureValidStates function returns a valid installation state.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
/// Specifies the feature name.
///
///
/// Receives the location to hold the valid installation states. For each valid installation state, the installer sets pInstallState
/// to a combination of the following values. This parameter should not be null.
///
///
///
/// Decimal Value
/// Meaning
///
/// -
/// 2 INSTALLSTATE_ADVERTISED
/// The feature can be advertised.
///
/// -
/// 4 INSTALLSTATE_ABSENT
/// The feature can be absent.
///
/// -
/// 8 INSTALLSTATE_LOCAL
/// The feature can be installed on the local drive.
///
/// -
/// 16 INSTALLSTATE_SOURCE
/// The feature can be configured to run from source, CD-ROM, or network.
///
/// -
/// 32 INSTALLSTATE_DEFAULT
/// The feature can be configured to use the default location: local or source.
///
///
///
/// The MsiGetFeatureValidStates function returns the following values:
///
/// See Calling Database Functions From Programs.
///
/// The MsiGetFeatureValidStates function determines state validity by querying all components that are linked to the
/// specified feature without taking into account the current installed state of any component.
///
/// The possible valid states for a feature are determined as follows:
///
/// -
/// If the feature does not contain components, both INSTALLSTATE_LOCAL and INSTALLSTATE_SOURCE are valid states for the feature.
///
/// -
///
/// If at least one component of the feature has an attribute of msidbComponentAttributesLocalOnly or
/// msidbComponentAttributesOptional, INSTALLSTATE_LOCAL is a valid state for the feature.
///
///
/// -
///
/// If at least one component of the feature has an attribute of msidbComponentAttributesSourceOnly or
/// msidbComponentAttributesOptional, INSTALLSTATE_SOURCE is a valid state for the feature.
///
///
/// -
///
/// If a file of a component that belongs to the feature is patched or from a compressed source, then INSTALLSTATE_SOURCE is not
/// included as a valid state for the feature.
///
///
/// -
///
/// INSTALLSTATE_ADVERTISE is not a valid state if the feature disallows advertisement (msidbFeatureAttributesDisallowAdvertise) or
/// the feature requires platform support for advertisement (msidbFeatureAttributesNoUnsupportedAdvertise) and the platform does not
/// support it.
///
///
/// -
/// INSTALLSTATE_ABSENT is a valid state for the feature if its attributes do not include msidbFeatureAttributesUIDisallowAbsent.
///
/// -
///
/// Valid states for child features marked to follow the parent feature (msidbFeatureAttributesFollowParent) are based upon the
/// parent feature's action or installed state.
///
///
///
///
/// After calling MsiGetFeatureValidStates a conditional statement may then be used to test the valid installation states of
/// a feature. For example, the following call to MsiGetFeatureValidStates gets the installation state of Feature1.
///
///
/// MsiGetFeatureValidStates(hProduct, "Feature1", &dwValidStates);
///
///
/// If Feature1 has attributes of value 0 (favor local), and Feature1 has one component with attributes of value 0 (local only), the
/// value of dwValidStates after the call is 14. This indicates that INSTALLSTATE_LOCAL, INSTALLSTATE_ABSENT,and
/// INSTALLSTATE_ADVERTISED are valid states for Feature1. The following conditional statement evaluates to True if local is a valid
/// state for this feature.
///
/// ( ( dwValidStates & ( 1 << INSTALLSTATE_LOCAL ) ) == ( 1 << INSTALLSTATE_LOCAL ) )
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msigetfeaturevalidstatesw UINT MsiGetFeatureValidStatesW(
// MSIHANDLE hInstall, LPCWSTR szFeature, LPDWORD lpInstallStates );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiGetFeatureValidStatesW")]
public static extern Win32Error MsiGetFeatureValidStates(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szFeature, out INSTALLSTATE lpInstallStates);
/// The MsiGetLanguage function returns the numeric language of the installation that is currently running.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
///
/// If the function succeeds, the return value is the numeric LANGID for the install.
/// If the function fails, the return value can be the following value.
///
/// The MsiGetLanguage function returns 0 if an installation is not running.
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msigetlanguage LANGID MsiGetLanguage( MSIHANDLE hInstall );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiGetLanguage")]
public static extern ushort MsiGetLanguage(MSIHANDLE hInstall);
///
/// The MsiGetLastErrorRecord function returns the error record that was last returned for the calling process. This function
/// returns a handle that should be closed using MsiCloseHandle.
///
/// A handle to the error record. If the last function was successful, MsiGetLastErrorRecord returns a null MSIHANDLE.
///
///
/// With the MsiGetLastErrorRecord function, field 1 of the record contains the installer error code. Other fields contain
/// data specific to the particular error. The error record is released internally after this function is run.
///
///
/// If the record is passed to MsiProcessMessage, it is formatted by looking up the string in the current database. If there is no
/// installation session but a product database is open, the format string may be obtained by a query on the Error table using the
/// error code, followed by a call to MsiFormatRecord. If the error code is known, the parameters may be individually interpreted.
///
///
/// The following functions set the per-process error record or reset it to null if no error occurred. MsiGetLastErrorRecord
/// also clears the error record after returning it.
///
///
/// -
/// MsiOpenDatabase
///
/// -
/// MsiDatabaseCommit
///
/// -
/// MsiDatabaseOpenView
///
/// -
/// MsiDatabaseImport
///
/// -
/// MsiDatabaseExport
///
/// -
/// MsiDatabaseMerge
///
/// -
/// MsiDatabaseGenerateTransform
///
/// -
/// MsiDatabaseApplyTransform
///
/// -
/// MsiViewExecute
///
/// -
/// MsiViewModify
///
/// -
/// MsiRecordSetStream
///
/// -
/// MsiGetSummaryInformation
///
/// -
/// MsiGetSourcePath
///
/// -
/// MsiGetTargetPath
///
/// -
/// MsiSetTargetPath
///
/// -
/// MsiGetComponentState
///
/// -
/// MsiSetComponentState
///
/// -
/// MsiGetFeatureState
///
/// -
/// MsiSetFeatureState
///
/// -
/// MsiGetFeatureCost
///
/// -
/// MsiGetFeatureValidStates
///
/// -
/// MsiSetInstallLevel
///
///
///
/// Note that it is recommended to use variables of type PMSIHANDLE because the installer closes PMSIHANDLE objects as they go out
/// of scope, whereas you must close MSIHANDLE objects by calling MsiCloseHandle. For more information see Use PMSIHANDLE instead of
/// HANDLE section in the Windows Installer Best Practices.
///
///
/// The following sample uses a call to MsiDatabaseOpenView to show how to obtain extended error information from one of the Windows
/// Installer functions that supports MsiGetLastErrorRecord. The example, OpenViewOnDatabase, attempts to open a view on a
/// database handle. The hDatabase handle can be obtained by a call to MsiOpenDatabase. If opening the view fails, the function then
/// tries to obtain extended error information by using MsiGetLastErrorRecord.
///
///
/// #include <windows.h> #include <Msiquery.h> #pragma comment(lib, "msi.lib") //------------------------------------------------------------------- // Function: OpenViewOnDatabase // // Arguments: hDatabase - handle to a MSI package obtained // via a call to MsiOpenDatabase // // Returns: UINT status code. ERROR_SUCCESS for success. //-------------------------------------------------------------------------------------------------- UINT __stdcall OpenViewOnDatabase(MSIHANDLE hDatabase) { if (!hDatabase) return ERROR_INVALID_PARAMETER; PMSIHANDLE hView = 0; UINT uiReturn = MsiDatabaseOpenView(hDatabase, TEXT("SELECT * FROM `UnknownTable`"), &hView); if (ERROR_SUCCESS != uiReturn) { // try to obtain extended error information. PMSIHANDLE hLastErrorRec = MsiGetLastErrorRecord(); TCHAR* szExtendedError = NULL; DWORD cchExtendedError = 0; if (hLastErrorRec) { // Since we are not currently calling MsiFormatRecord during an // install session, hInstall is NULL. If MsiFormatRecord was called // via a DLL custom action, the hInstall handle provided to the DLL // custom action entry point could be used to further resolve // properties that might be contained within the error record. // To determine the size of the buffer required for the text, // szResultBuf must be provided as an empty string with // *pcchResultBuf set to 0. UINT uiStatus = MsiFormatRecord(NULL, hLastErrorRec, TEXT(""), &cchExtendedError); if (ERROR_MORE_DATA == uiStatus) { // returned size does not include null terminator. cchExtendedError++; szExtendedError = new TCHAR[cchExtendedError]; if (szExtendedError) { uiStatus = MsiFormatRecord(NULL, hLastErrorRec, szExtendedError, &cchExtendedError); if (ERROR_SUCCESS == uiStatus) { // We now have an extended error // message to report. // PLACE ADDITIONAL CODE HERE // TO LOG THE ERROR MESSAGE // IN szExtendedError. } delete [] szExtendedError; szExtendedError = NULL; } } } } return uiReturn; }
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msigetlasterrorrecord MSIHANDLE MsiGetLastErrorRecord();
[DllImport(Lib_Msi, SetLastError = true, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiGetLastErrorRecord")]
public static extern PMSIHANDLE MsiGetLastErrorRecord();
///
/// The MsiGetMode function is used to determine whether the installer is currently running in a specified mode, as listed in
/// the table. The function returns a Boolean value of TRUE or FALSE, indicating whether the specific property passed
/// into the function is currently set ( TRUE) or not set ( FALSE).
///
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
///
/// Specifies the run mode. This parameter must have one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// MSIRUNMODE_ADMIN
/// The administrative mode is installing, or the product is installing.
///
/// -
/// MSIRUNMODE_ADVERTISE
/// The advertisements are installing or the product is installing or updating.
///
/// -
/// MSIRUNMODE_MAINTENANCE
/// An existing installation is being modified or there is a new installation.
///
/// -
/// MSIRUNMODE_ROLLBACKENABLED
/// Rollback is enabled.
///
/// -
/// MSIRUNMODE_LOGENABLED
/// The log file is active. It was enabled prior to the installation session.
///
/// -
/// MSIRUNMODE_OPERATIONS
/// Execute operations are in the determination phase.
///
/// -
/// MSIRUNMODE_REBOOTATEND
/// A reboot is necessary after a successful installation (settable).
///
/// -
/// MSIRUNMODE_REBOOTNOW
/// A reboot is necessary to continue the installation (settable).
///
/// -
/// MSIRUNMODE_CABINET
/// Files from cabinets and Media table files are installing.
///
/// -
/// MSIRUNMODE_SOURCESHORTNAMES
/// The source LongFileNames is suppressed through the PID_MSISOURCE summary property.
///
/// -
/// MSIRUNMODE_TARGETSHORTNAMES
/// The target LongFileNames is suppressed through the SHORTFILENAMES property.
///
/// -
/// MSIRUNMODE_RESERVED11
/// Reserved for future use.
///
/// -
/// MSIRUNMODE_WINDOWS9X
/// The operating system is a 9x version.
///
/// -
/// MSIRUNMODE_ZAWENABLED
/// The operating system supports demand installation.
///
/// -
/// MSIRUNMODE_RESERVED14
/// Reserved for future use.
///
/// -
/// MSIRUNMODE_RESERVED15
/// Reserved for future use.
///
/// -
/// MSIRUNMODE_SCHEDULED
/// A custom action called from install script execution.
///
/// -
/// MSIRUNMODE_ROLLBACK
/// A custom action called from rollback execution script.
///
/// -
/// MSIRUNMODE_COMMIT
/// A custom action called from commit execution script.
///
///
///
///
/// TRUE indicates the specific property passed into the function is currently set.
/// FALSE indicates the specific property passed into the function is currently not set.
///
///
/// Note that not all the run mode values of iRunMode are available when calling MsiGetMode from a deferred custom action.
/// For details, see Obtaining Context Information for Deferred Execution Custom Actions.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msigetmode BOOL MsiGetMode( MSIHANDLE hInstall,
// MSIRUNMODE eRunMode );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiGetMode")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE eRunMode);
/// The MsiGetProperty function gets the value for an installer property.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
/// A null-terminated string that specifies the name of the property.
///
/// Pointer to the buffer that receives the null terminated string containing the value of the property. Do not attempt to determine
/// the size of the buffer by passing in a null (value=0) for szValueBuf. You can get the size of the buffer by passing in an empty
/// string (for example ""). The function will then return ERROR_MORE_DATA and pchValueBuf will contain the required buffer size in
/// TCHARs, not including the terminating null character. On return of ERROR_SUCCESS, pcchValueBuf contains the number of TCHARs
/// written to the buffer, not including the terminating null character.
///
///
/// Pointer to the variable that specifies the size, in TCHARs, of the buffer pointed to by the variable szValueBuf. When the
/// function returns ERROR_SUCCESS, this variable contains the size of the data copied to szValueBuf, not including the terminating
/// null character. If szValueBuf is not large enough, the function returns ERROR_MORE_DATA and stores the required size, not
/// including the terminating null character, in the variable pointed to by pchValueBuf.
///
/// This function returns UINT.
///
///
/// If the value for the property retrieved by the MsiGetProperty function is not defined, it is equivalent to a 0-length
/// value. It is not an error.
///
///
/// If ERROR_MORE_DATA is returned, the parameter which is a pointer gives the size of the buffer required to hold the string. If
/// ERROR_SUCCESS is returned, it gives the number of characters written to the string buffer. Therefore you can get the size of the
/// buffer by passing in an empty string (for example "") for the parameter that specifies the buffer. Do not attempt to determine
/// the size of the buffer by passing in a Null (value=0).
///
///
/// The following example shows how a DLL custom action could access the value of a property by dynamically determining the size of
/// the value buffer.
///
///
/// UINT __stdcall MyCustomAction(MSIHANDLE hInstall) { TCHAR* szValueBuf = NULL; DWORD cchValueBuf = 0; UINT uiStat = MsiGetProperty(hInstall, TEXT("MyProperty"), TEXT(""), &cchValueBuf); //cchValueBuf now contains the size of the property's string, without null termination if (ERROR_MORE_DATA == uiStat) { ++cchValueBuf; // add 1 for null termination szValueBuf = new TCHAR[cchValueBuf]; if (szValueBuf) { uiStat = MsiGetProperty(hInstall, TEXT("MyProperty"), szValueBuf, &cchValueBuf); } } if (ERROR_SUCCESS != uiStat) { if (szValueBuf != NULL) delete[] szValueBuf; return ERROR_INSTALL_FAILURE; } // custom action uses MyProperty // ... delete[] szValueBuf; return ERROR_SUCCESS; }
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msigetpropertya UINT MsiGetPropertyA( MSIHANDLE hInstall,
// LPCSTR szName, LPSTR szValueBuf, LPDWORD pcchValueBuf );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiGetPropertyA")]
public static extern Win32Error MsiGetProperty(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szName,
[Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder szValueBuf, ref uint pcchValueBuf);
/// The MsiGetSourcePath function returns the full source path for a folder in the Directory table.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
///
/// A null-terminated string that specifies a record of the Directory table. If the directory is a root directory, this can be a
/// value from the DefaultDir column. Otherwise it must be a value from the Directory column.
///
///
/// Pointer to the buffer that receives the null terminated full source path. Do not attempt to determine the size of the buffer by
/// passing in a null (value=0) for szPathBuf. You can get the size of the buffer by passing in an empty string (for example "").
/// The function then returns ERROR_MORE_DATA and pcchPathBuf contains the required buffer size in TCHARs, not including the
/// terminating null character. On return of ERROR_SUCCESS, pcchPathBuf contains the number of TCHARs written to the buffer, not
/// including the terminating null character.
///
///
/// Pointer to the variable that specifies the size, in TCHARs, of the buffer pointed to by the variable szPathBuf. When the
/// function returns ERROR_SUCCESS, this variable contains the size of the data copied to szPathBuf, not including the terminating
/// null character. If szPathBuf is not large enough, the function returns ERROR_MORE_DATA and stores the required size, not
/// including the terminating null character, in the variable pointed to by pcchPathBuf.
///
/// The MsiGetSourcePath function returns the following values:
///
///
/// Before calling this function, the installer must first run the CostInitialize action, FileCost action, and CostFinalize action.
/// For more information, see Calling Database Functions from Programs.
///
///
/// If ERROR_MORE_DATA is returned, the parameter which is a pointer gives the size of the buffer required to hold the string. If
/// ERROR_SUCCESS is returned, it gives the number of characters written to the string buffer. Therefore you can get the size of the
/// buffer by passing in an empty string (for example "") for the parameter that specifies the buffer. Do not attempt to determine
/// the size of the buffer by passing in a Null (value=0).
///
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msigetsourcepatha UINT MsiGetSourcePathA( MSIHANDLE
// hInstall, LPCSTR szFolder, LPSTR szPathBuf, LPDWORD pcchPathBuf );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiGetSourcePathA")]
public static extern Win32Error MsiGetSourcePath(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szFolder,
[Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder szPathBuf, ref uint pcchPathBuf);
///
/// The MsiGetSummaryInformation function obtains a handle to the _SummaryInformation stream for an installer database. This
/// function returns a handle that should be closed using MsiCloseHandle.
///
/// Handle to the database.
/// Specifies the path to the database.
/// Specifies the maximum number of updated values.
/// Pointer to the location from which to receive the summary information handle.
/// The MsiGetSummaryInformation function returns the following values:
///
///
/// If the database specified by the MsiGetSummaryInformation function is not open, you must specify 0 for hDatabase and
/// specify the path to the database in szDatabasePath. If the database is open, you must set szDatabasePath to 0.
///
///
/// If a value of uiUpdateCount greater than 0 is used to open an existing summary information stream, MsiSummaryInfoPersist must be
/// called before closing the phSummaryInfo handle. Failing to do this will lose the existing stream information.
///
///
/// To view the summary information of a patch using MsiGetSummaryInformation, set szDatabasePath to the path to the patch.
/// Alternately, you can create a handle to the patch using MsiOpenDatabase and then pass that handle to
/// MsiGetSummaryInformation as the hDatabase parameter.
///
///
/// Note that it is recommended to use variables of type PMSIHANDLE because the installer closes PMSIHANDLE objects as they go out
/// of scope, whereas you must close MSIHANDLE objects by calling MsiCloseHandle. For more information see Use PMSIHANDLE instead of
/// HANDLE section in the Windows Installer Best Practices.
///
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msigetsummaryinformationw UINT MsiGetSummaryInformationW(
// MSIHANDLE hDatabase, LPCWSTR szDatabasePath, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiGetSummaryInformationW")]
public static extern Win32Error MsiGetSummaryInformation(MSIHANDLE hDatabase, [MarshalAs(UnmanagedType.LPTStr)] string szDatabasePath,
uint uiUpdateCount, out PMSIHANDLE phSummaryInfo);
/// The MsiGetTargetPath function returns the full target path for a folder in the Directory table.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
///
/// A null-terminated string that specifies a record of the Directory table. If the directory is a root directory, this can be a
/// value from the DefaultDir column. Otherwise it must be a value from the Directory column.
///
///
/// Pointer to the buffer that receives the null terminated full target path. Do not attempt to determine the size of the buffer by
/// passing in a null (value=0) for szPathBuf. You can get the size of the buffer by passing in an empty string (for example "").
/// The function then returns ERROR_MORE_DATA and pcchPathBuf contains the required buffer size in TCHARs, not including the
/// terminating null character. On return of ERROR_SUCCESS, pcchPathBuf contains the number of TCHARs written to the buffer, not
/// including the terminating null character.
///
///
/// Pointer to the variable that specifies the size, in TCHARs, of the buffer pointed to by the variable szPathBuf When the
/// function returns ERROR_SUCCESS, this variable contains the size of the data copied to szPathBuf, not including the terminating
/// null character. If szPathBuf is not large enough, the function returns ERROR_MORE_DATA and stores the required size, not
/// including the terminating null character, in the variable pointed to by pcchPathBuf.
///
/// The MsiGetTargetPath function returns the following values:
///
///
/// If ERROR_MORE_DATA is returned, the parameter which is a pointer gives the size of the buffer required to hold the string. If
/// ERROR_SUCCESS is returned, it gives the number of characters written to the string buffer. Therefore you can get the size of the
/// buffer by passing in an empty string (for example "") for the parameter that specifies the buffer. Do not attempt to determine
/// the size of the buffer by passing in a Null (value=0).
///
///
/// Before calling this function, the installer must first run the CostInitialize action, FileCost action, and CostFinalize action.
/// For more information, see Calling Database Functions from Programs.
///
///
/// MsiGetTargetPath returns the default path of the target directory authored in the package if the target's current
/// location is unavailable for an installation. For example, if during a Maintenance Installation a target directory at a network
/// location is unavailable, the installer resets the target directory paths back to their defaults. To get the actual path of the
/// target directory in this case call MsiProvideComponent for a component that is known to have been previously installed into the
/// searched for directory and set dwInstallMode to INSTALLMODE_NODETECTION.
///
/// For more information, see Calling Database Functions From Programs.
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msigettargetpatha UINT MsiGetTargetPathA( MSIHANDLE
// hInstall, LPCSTR szFolder, LPSTR szPathBuf, LPDWORD pcchPathBuf );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiGetTargetPathA")]
public static extern Win32Error MsiGetTargetPath(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szFolder,
[Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder szPathBuf, ref uint pcchPathBuf);
///
/// The MsiOpenDatabase function opens a database file for data access. This function returns a handle that should be closed
/// using MsiCloseHandle.
///
/// Specifies the full path or relative path to the database file.
///
///
/// Receives the full path to the file or the persistence mode. You can use the szPersist parameter to direct the persistent output
/// to a new file or to specify one of the following predefined persistence modes.
///
///
///
/// Value
/// Meaning
///
/// -
/// MSIDBOPEN_CREATEDIRECT
/// Create a new database, direct mode read/write.
///
/// -
/// MSIDBOPEN_CREATE
/// Create a new database, transact mode read/write.
///
/// -
/// MSIDBOPEN_DIRECT
/// Open a database direct read/write without transaction.
///
/// -
/// MSIDBOPEN_READONLY
/// Open a database read-only, no persistent changes.
///
/// -
/// MSIDBOPEN_TRANSACT
/// Open a database read/write in transaction mode.
///
/// -
/// MSIDBOPEN_PATCHFILE
/// Add this flag to indicate a patch file.
///
///
///
/// Pointer to the location of the returned database handle.
/// The MsiOpenDatabase function returns the following values:
///
///
/// To make and save changes to a database first open the database in transaction (MSIDBOPEN_TRANSACT), create (MSIDBOPEN_CREATE or
/// MSIDBOPEN_CREATEDIRECT), or direct (MSIDBOPEN_DIRECT) mode. After making the changes, always call MsiDatabaseCommit before
/// closing the database handle. MsiDatabaseCommit flushes all buffers.
///
///
/// Always call MsiDatabaseCommit on a database that has been opened in direct mode (MSIDBOPEN_DIRECT or MSIDBOPEN_CREATEDIRECT)
/// before closing the database's handle. Failure to do this may corrupt the database.
///
/// Because MsiOpenDatabase initiates database access, it cannot be used with a running installation.
///
/// Note that it is recommended to use variables of type PMSIHANDLE because the installer closes PMSIHANDLE objects as they go out
/// of scope, whereas you must close MSIHANDLE objects by calling MsiCloseHandle. For more information see Use PMSIHANDLE instead of
/// HANDLE section in the Windows Installer Best Practices.
///
///
/// Note When a database is opened as the output of another database, the summary information stream of the output database
/// is actually a read-only mirror of the original database, and, thus, cannot be changed. Additionally, it is not persisted with
/// the database. To create or modify the summary information for the output database, it must be closed and reopened.
///
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msiopendatabasea UINT MsiOpenDatabaseA( LPCSTR
// szDatabasePath, LPCSTR szPersist, MSIHANDLE *phDatabase );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiOpenDatabaseA")]
public static extern Win32Error MsiOpenDatabase([MarshalAs(UnmanagedType.LPTStr)] string szDatabasePath,
[MarshalAs(UnmanagedType.LPTStr)] string szPersist, out PMSIHANDLE phDatabase);
///
/// The MsiOpenDatabase function opens a database file for data access. This function returns a handle that should be closed
/// using MsiCloseHandle.
///
/// Specifies the full path or relative path to the database file.
///
///
/// Receives the full path to the file or the persistence mode. You can use the szPersist parameter to direct the persistent output
/// to a new file or to specify one of the following predefined persistence modes.
///
///
///
/// Value
/// Meaning
///
/// -
/// MSIDBOPEN_CREATEDIRECT
/// Create a new database, direct mode read/write.
///
/// -
/// MSIDBOPEN_CREATE
/// Create a new database, transact mode read/write.
///
/// -
/// MSIDBOPEN_DIRECT
/// Open a database direct read/write without transaction.
///
/// -
/// MSIDBOPEN_READONLY
/// Open a database read-only, no persistent changes.
///
/// -
/// MSIDBOPEN_TRANSACT
/// Open a database read/write in transaction mode.
///
/// -
/// MSIDBOPEN_PATCHFILE
/// Add this flag to indicate a patch file.
///
///
///
/// Pointer to the location of the returned database handle.
/// The MsiOpenDatabase function returns the following values:
///
///
/// To make and save changes to a database first open the database in transaction (MSIDBOPEN_TRANSACT), create (MSIDBOPEN_CREATE or
/// MSIDBOPEN_CREATEDIRECT), or direct (MSIDBOPEN_DIRECT) mode. After making the changes, always call MsiDatabaseCommit before
/// closing the database handle. MsiDatabaseCommit flushes all buffers.
///
///
/// Always call MsiDatabaseCommit on a database that has been opened in direct mode (MSIDBOPEN_DIRECT or MSIDBOPEN_CREATEDIRECT)
/// before closing the database's handle. Failure to do this may corrupt the database.
///
/// Because MsiOpenDatabase initiates database access, it cannot be used with a running installation.
///
/// Note that it is recommended to use variables of type PMSIHANDLE because the installer closes PMSIHANDLE objects as they go out
/// of scope, whereas you must close MSIHANDLE objects by calling MsiCloseHandle. For more information see Use PMSIHANDLE instead of
/// HANDLE section in the Windows Installer Best Practices.
///
///
/// Note When a database is opened as the output of another database, the summary information stream of the output database
/// is actually a read-only mirror of the original database, and, thus, cannot be changed. Additionally, it is not persisted with
/// the database. To create or modify the summary information for the output database, it must be closed and reopened.
///
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msiopendatabasea UINT MsiOpenDatabaseA( LPCSTR
// szDatabasePath, LPCSTR szPersist, MSIHANDLE *phDatabase );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiOpenDatabaseA")]
public static extern Win32Error MsiOpenDatabase([MarshalAs(UnmanagedType.LPTStr)] string szDatabasePath,
[In] IntPtr szPersist, out PMSIHANDLE phDatabase);
// Database open read-only, no persistent changes
// Database read/write in transaction mode
// Database direct read/write without transaction
// Create new database, transact mode read/write
// Create new database, direct mode read/write
// add flag to indicate patch file
/// The MsiPreviewBillboard function displays a billboard with the host control in the displayed dialog box.
/// Handle to the preview.
/// Specifies the name of the host control.
/// Specifies the name of the billboard to display.
/// This function returns UINT.
/// Supplying a null billboard name in the MsiPreviewBillboard function removes any billboard displayed.
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msipreviewbillboarda UINT MsiPreviewBillboardA( MSIHANDLE
// hPreview, LPCSTR szControlName, LPCSTR szBillboard );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiPreviewBillboardA")]
public static extern Win32Error MsiPreviewBillboard(MSIHANDLE hPreview, [MarshalAs(UnmanagedType.LPTStr)] string szControlName,
[Optional, MarshalAs(UnmanagedType.LPTStr)] string szBillboard);
/// The MsiPreviewDialog function displays a dialog box as modeless and inactive.
/// Handle to the preview.
/// Specifies the name of the dialog box to preview.
/// This function returns UINT.
/// Supplying a null name in the MsiPreviewDialog function removes any current dialog box.
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msipreviewdialogw UINT MsiPreviewDialogW( MSIHANDLE
// hPreview, LPCWSTR szDialogName );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiPreviewDialogW")]
public static extern Win32Error MsiPreviewDialog(MSIHANDLE hPreview, [MarshalAs(UnmanagedType.LPTStr)] string szDialogName);
/// The MsiProcessMessage function sends an error record to the installer for processing.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
///
///
/// The eMessage parameter must be a value specifying one of the following message types. To display a message box with push buttons
/// or icons, use OR-operators to add INSTALLMESSAGE_ERROR, INSTALLMESSAGE_WARNING, or INSTALLMESSAGE_USER to the standard message
/// box styles used by the MessageBox and MessageBoxEx functions. For more information, see the Remarks below.
///
///
///
/// Value
/// Meaning
///
/// -
/// INSTALLMESSAGE_FATALEXIT
/// Premature termination, possibly fatal out of memory.
///
/// -
/// INSTALLMESSAGE_ERROR
/// Formatted error message,[1] is message number in Error table.
///
/// -
/// INSTALLMESSAGE_WARNING
/// Formatted warning message,[1] is message number in Error table.
///
/// -
/// INSTALLMESSAGE_USER
/// User request message,[1] is message number in Error table.
///
/// -
/// INSTALLMESSAGE_INFO
/// Informative message for log,not to be displayed.
///
/// -
/// INSTALLMESSAGE_FILESINUSE
/// List of files currently in use that must be closed before being replaced.
///
/// -
/// INSTALLMESSAGE_RESOLVESOURCE
/// Request to determine a valid source location.
///
/// -
/// INSTALLMESSAGE_RMFILESINUSE
///
/// List of files currently in use that must be closed before being replaced. Available beginning with Windows Installer version
/// 4.0. For more information about this message see Using Restart Manager with an External UI.
///
///
/// -
/// INSTALLMESSAGE_OUTOFDISKSPACE
/// Insufficient disk space message.
///
/// -
/// INSTALLMESSAGE_ACTIONSTART
/// Progress: start of action,[1] action name,[2] description,[3] template for ACTIONDATA messages.
///
/// -
/// INSTALLMESSAGE_ACTIONDATA
/// Action data. Record fields correspond to the template of ACTIONSTART message.
///
/// -
/// INSTALLMESSAGE_PROGRESS
/// Progress bar information. See the description of record fields below.
///
/// -
/// INSTALLMESSAGE_COMMONDATA
/// 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
///
///
///
/// Handle to a record containing message format and data.
/// This function returns int.
///
///
/// The MsiProcessMessage function performs any enabled logging operations and defers execution. You can selectively enable
/// logging for various message types.
///
///
/// For INSTALLMESSAGE_FATALEXIT, INSTALLMESSAGE_ERROR, INSTALLMESSAGE_WARNING, and INSTALLMESSAGE_USER messages, if field 0 is not
/// set field 1 must be set to the error code corresponding to the error message in the Error table. Then, the message is formatted
/// using the template from the Error table before passing it to the user-interface handler for display.
///
/// Record Fields for Progress Bar Messages
///
/// The following describes the record fields when eMessageType is set to INSTALLMESSAGE_PROGRESS. Field 1 specifies the type of the
/// progress message. The meaning of the other fields depend upon the value in this field. The possible values that can be set into
/// Field 1 are as follows.
///
///
///
/// Field 1 value
/// Field 1 description
///
/// -
/// 0
/// Resets progress bar and sets the expected total number of ticks in the bar.
///
/// -
/// 1
/// Provides information related to progress messages to be sent by the current action.
///
/// -
/// 2
/// Increments the progress bar.
///
/// -
/// 3
/// Enables an action (such as CustomAction) to add ticks to the expected total number of progress of the progress bar.
///
///
/// The meaning of Field 2 depends upon the value in Field 1 as follows.
///
///
/// Field 1 value
/// Field 2 description
///
/// -
/// 0
/// Expected total number of ticks in the progress bar.
///
/// -
/// 1
///
/// Number of ticks the progress bar moves for each ActionData message that is sent by the current action. This field is ignored if
/// Field 3 is 0.
///
///
/// -
/// 2
/// Number of ticks the progress bar has moved.
///
/// -
/// 3
/// Number of ticks to add to total expected progress.
///
///
/// The meaning of Field 3 depends upon the value in Field 1 as follows.
///
///
/// Field 1 value
/// Field 3 value
/// Field 3 description
///
/// -
/// 0
/// 0
/// Forward progress bar (left to right)
///
/// -
///
/// 1
/// Backward progress bar (right to left)
///
/// -
/// 1
/// 0
/// The current action will send explicit ProgressReport messages.
///
/// -
///
/// 1
///
/// Increment the progress bar by the number of ticks specified in Field 2 each time an ActionData message is sent by the current action.
///
///
/// -
/// 2
/// Unused
///
///
/// -
/// 3
/// Unused
///
///
///
/// The meaning of Field 4 depends upon the value in Field 1 as follows.
///
///
/// Field 1 value
/// Field 4 value
/// Field 4 description
///
/// -
/// 0
/// 0
/// Execution is in progress. In this case, the UI could calculate and display the time remaining.
///
/// -
///
/// 1
///
/// Creating the execution script. In this case, the UI could display a message to please wait while the installer finishes
/// preparing the installation.
///
///
/// -
/// 1
/// Unused
///
///
/// -
/// 2
/// Unused
///
///
/// -
/// 3
/// Unused
///
///
///
/// For more information and a code sample, see Adding Custom Actions to the ProgressBar.
/// Display of Message Boxes
///
/// To display a message box with push buttons or icons, use OR-operators to add INSTALLMESSAGE_ERROR, INSTALLMESSAGE_WARNING, or
/// INSTALLMESSAGE_USER with the message box options used by MessageBox and MessageBoxEx. The available push button options are
/// MB_OK, MB_OKCANCEL, MB_ABORTRETRYIGNORE, MB_YESNOCANCEL, MB_YESNO, and MB_RETRYCANCEL. The available default button options are
/// MB_DEFBUTTON1, MB_DEFBUTTON2, and MB_DEFBUTTON3. The available icon options are MB_ICONERROR, MB_ICONQUESTION, MB_ICONWARNING,
/// and MB_ICONINFORMATION. If no icon options is specified, Windows Installer chooses a default icon style based upon the message type.
///
///
/// For example, the following call to MsiProcessMessage sends an INSTALLMESSAGE_ERROR message with the MB_ICONWARNING icon
/// and the MB_ABORTRETRYCANCEL buttons.
///
///
/// PMSIHANDLE hInstall; PMSIHANDLE hRec; MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_ERROR|MB_ABORTRETRYIGNORE|MB_ICONWARNING), hRec);
///
///
/// If a custom action calls MsiProcessMessage, the custom action should be capable of handling a cancellation by the user
/// and should return ERROR_INSTALL_USEREXIT.
///
///
/// For more information on sending messages with MsiProcessMessage, see the Sending Messages to Windows Installer Using MsiProcessMessage.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msiprocessmessage int MsiProcessMessage( MSIHANDLE
// hInstall, INSTALLMESSAGE eMessageType, MSIHANDLE hRecord );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiProcessMessage")]
public static extern int MsiProcessMessage(MSIHANDLE hInstall, INSTALLMESSAGE eMessageType, MSIHANDLE hRecord);
/// The MsiRecordClearData function sets all fields in a record to null.
/// Handle to the record.
/// This function returns UINT.
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msirecordcleardata UINT MsiRecordClearData( MSIHANDLE
// hRecord );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiRecordClearData")]
public static extern Win32Error MsiRecordClearData(MSIHANDLE hRecord);
///
/// The MsiRecordDataSize function returns the length of a record field. The count does not include the terminating null character.
///
/// Handle to the record.
/// Specifies a field of the record.
///
///
/// The MsiRecordDataSize function returns 0 if the field is null, nonexistent, or an internal object pointer. The function
/// also returns 0 if the handle is not a valid record handle.
///
/// If the data is in integer format, the function returns sizeof(int).
/// If the data is in string format, the function returns the character count (not including the null character).
/// If the data is in stream format, the function returns the byte count.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msirecorddatasize UINT MsiRecordDataSize( MSIHANDLE
// hRecord, UINT iField );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiRecordDataSize")]
public static extern uint MsiRecordDataSize(MSIHANDLE hRecord, uint iField);
/// The MsiRecordGetFieldCount function returns the number of fields in a record.
/// Handle to a record.
/// If the function succeeds, the return value is the number of fields in the record.
///
/// The count returned by the MsiRecordGetFieldCount parameter does not include field 0. Read access to fields beyond this
/// count returns null values. Write access fails.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msirecordgetfieldcount UINT MsiRecordGetFieldCount(
// MSIHANDLE hRecord );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiRecordGetFieldCount")]
public static extern uint MsiRecordGetFieldCount(MSIHANDLE hRecord);
/// The MsiRecordGetInteger function returns the integer value from a record field.
/// Handle to a record.
/// Specifies the field of the record from which to obtain the value.
/// If the function succeeds, the return value is the integer value of the field.
///
/// The MsiRecordGetInteger function returns MSI_NULL_INTEGER if the field is null or if the field is a string that
/// cannot be converted to an integer.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msirecordgetinteger int MsiRecordGetInteger( MSIHANDLE
// hRecord, UINT iField );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiRecordGetInteger")]
public static extern int MsiRecordGetInteger(MSIHANDLE hRecord, uint iField);
// integer value reserved for null
/// The MsiRecordGetString function returns the string value of a record field.
/// Handle to the record.
/// Specifies the field requested.
///
/// Pointer to the buffer that receives the null terminated string containing the value of the record field. Do not attempt to
/// determine the size of the buffer by passing in a null (value=0) for szValueBuf. You can get the size of the buffer by passing in
/// an empty string (for example ""). The function then returns ERROR_MORE_DATA and pcchValueBuf contains the required buffer
/// size in TCHARs, not including the terminating null character. On return of ERROR_SUCCESS, pcchValueBuf contains the
/// number of TCHARs written to the buffer, not including the terminating null character.
///
///
/// Pointer to the variable that specifies the size, in TCHAR s, of the buffer pointed to by the variable szValueBuf. When
/// the function returns ERROR_SUCCESS, this variable contains the size of the data copied to szValueBuf, not including the
/// terminating null character. If szValueBuf is not large enough, the function returns ERROR_MORE_DATA and stores the
/// required size, not including the terminating null character, in the variable pointed to by pcchValueBuf.
///
/// The MsiRecordGetString function returns one of the following values:
///
/// If ERROR_MORE_DATA is returned, the parameter which is a pointer gives the size of the buffer required to hold the
/// string. If ERROR_SUCCESS is returned, it gives the number of characters written to the string buffer. To get the size of
/// the buffer, pass in the address of a 1 character buffer as szValueBuf and specify the size of the buffer with pcchValueBuf as 0.
/// This ensures that no string value returned by the function fits into the buffer. Do not attempt to determine the size of the
/// buffer by passing in a Null (value=0).
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msirecordgetstringa UINT MsiRecordGetStringA( MSIHANDLE
// hRecord, UINT iField, LPSTR szValueBuf, LPDWORD pcchValueBuf );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiRecordGetStringA")]
public static extern Win32Error MsiRecordGetString(MSIHANDLE hRecord, uint iField, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder szValueBuf, ref uint pcchValueBuf);
/// The MsiRecordIsNull function reports a null record field.
/// Handle to a record.
/// Specifies the field to check.
/// This function returns BOOL.
/// The iField parameter is based on 1 (one).
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msirecordisnull BOOL MsiRecordIsNull( MSIHANDLE hRecord,
// UINT iField );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiRecordIsNull")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool MsiRecordIsNull(MSIHANDLE hRecord, uint iField);
/// The MsiRecordReadStream function reads bytes from a record stream field into a buffer.
/// Handle to the record.
/// Specifies the field of the record.
///
/// A buffer to receive the stream field. You should ensure the destination buffer is the same size or larger than the source
/// buffer. See the Remarks section.
///
///
/// Specifies the in and out buffer count. On input, this is the full size of the buffer. On output, this is the number of bytes
/// that were actually written to the buffer. See the Remarks section.
///
/// This function returns UINT.
///
///
/// To read a stream, set pcbDataBuf to the number of bytes that are to be transferred from stream to buffer each time the function
/// is called. On return, the MsiRecordReadStream resets pcbDataBuf to the number of bytes that were actually transferred. If
/// the buffer is smaller than the stream, the stream is repositioned when the buffer becomes full such that the next data in the
/// stream is transferred by the next call to the function. When no more bytes are available, MsiRecordReadStream returns ERROR_SUCCESS.
///
/// If you pass 0 for szDataBuf then pcbDataBuf is reset to the number of bytes in the stream remaining to be read.
///
/// The following code sample reads from a stream that is in field 1 of a record specified by hRecord and reads the entire stream 8
/// bytes at a time.
///
///
/// char szBuffer[8]; PMSIHANDLE hRecord; DWORD cbBuf = sizeof(szBuffer); do { if (MsiRecordReadStream(hRecord, 1, szBuffer, &cbBuf) != ERROR_SUCCESS) break; /* error */ } while (cbBuf == 8); //continue reading the stream while you receive a full buffer //cbBuf will be less once you reach the end of the stream and cannot fill your //buffer with stream data
///
/// See also OLE Limitations on Streams.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msirecordreadstream UINT MsiRecordReadStream( MSIHANDLE
// hRecord, UINT iField, char *szDataBuf, LPDWORD pcbDataBuf );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiRecordReadStream")]
public static extern Win32Error MsiRecordReadStream(MSIHANDLE hRecord, uint iField, [Out] IntPtr szDataBuf, ref uint pcbDataBuf);
/// The MsiRecordSetInteger function sets a record field to an integer field.
/// Handle to the record.
/// Specifies the field of the record to set.
/// Specifies the value to which to set the field.
/// This function returns UINT.
///
///
/// In the MsiRecordSetInteger function, attempting to store a value in a nonexistent field causes an error. Note that the
/// following code returns ERROR_INVALID_PARAMETER.
///
///
/// MSIHANDLE hRecord; UINT lReturn; //create an msirecord with no fields hRecord = MsiCreateRecord(0); //attempting to set the first field's value gives you ERROR_INVALID_PARAMETER lReturn = MsiRecordSetInteger(hRecord, 1, 0);
///
/// To set a record integer field to NULL_INTEGER, set iValue to MSI_NULL_INTEGER.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msirecordsetinteger UINT MsiRecordSetInteger( MSIHANDLE
// hRecord, UINT iField, int iValue );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiRecordSetInteger")]
public static extern Win32Error MsiRecordSetInteger(MSIHANDLE hRecord, uint iField, int iValue);
///
/// The MsiRecordSetStream function sets a record stream field from a file. Stream data cannot be inserted into temporary fields.
///
/// Handle to the record.
/// Specifies the field of the record to set.
/// Specifies the path to the file containing the stream.
/// The MsiRecordSetStream function returns the following values:
///
///
/// The contents of the file specified in the MsiRecordSetStream function is read into a stream object. The stream persists
/// if the record is inserted into the database and the database is committed.
///
///
/// To reset the stream to its beginning you must pass in a Null pointer for szFilePath. Do not pass a pointer to an empty string,
/// "", to reset the stream.
///
/// See also OLE Limitations on Streams.
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msirecordsetstreama UINT MsiRecordSetStreamA( MSIHANDLE
// hRecord, UINT iField, LPCSTR szFilePath );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiRecordSetStreamA")]
public static extern Win32Error MsiRecordSetStream(MSIHANDLE hRecord, uint iField, [MarshalAs(UnmanagedType.LPTStr)] string szFilePath);
/// The MsiRecordSetString function copies a string into the designated field.
/// Handle to the record.
/// Specifies the field of the record to set.
/// Specifies the string value of the field.
/// This function returns UINT.
///
///
/// In the MsiRecordSetString function, a null string pointer and an empty string both set the field to null. Attempting to
/// store a value in a nonexistent field causes an error.
///
/// To set a record string field to null, set szValue to either a null string or an empty string.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msirecordsetstringa UINT MsiRecordSetStringA( MSIHANDLE
// hRecord, UINT iField, LPCSTR szValue );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiRecordSetStringA")]
public static extern Win32Error MsiRecordSetString(MSIHANDLE hRecord, uint iField, [MarshalAs(UnmanagedType.LPTStr)] string szValue);
/// The MsiSequence function executes another action sequence, as described in the specified table.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
/// Specifies the name of the table containing the action sequence.
/// This parameter is currently unimplemented. It is reserved for future use and must be 0.
/// This function returns UINT.
///
///
/// The MsiSequence function queries the specified table, ordering the actions by the numbers in the Sequence column. For
/// each row retrieved, an action is executed, provided that any supplied condition expression does not evaluate to FALSE.
///
///
/// An action sequence containing any actions that update the system, such as the InstallFiles and WriteRegistryValues actions,
/// cannot be run by calling MsiSequence. The exception to this rule is if MsiSequence is called from a custom action
/// that is scheduled in the InstallExecuteSequence table between the InstallInitialize and InstallFinalize actions. Actions that do
/// not update the system, such as AppSearch or CostInitialize, can be called.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msisequencew UINT MsiSequenceW( MSIHANDLE hInstall,
// LPCWSTR szTable, INT iSequenceMode );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiSequenceW")]
public static extern Win32Error MsiSequence(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szTable, int iSequenceMode = 0);
/// The MsiSetComponentState function sets a component to the requested state.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
/// Specifies the name of the component.
///
/// Specifies the state to set. This parameter can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// INSTALLSTATE_ABSENT
/// The component was uninstalled.
///
/// -
/// INSTALLSTATE_LOCAL
/// The component was installed on the local drive.
///
/// -
/// INSTALLSTATE_SOURCE
/// The component will run from source, CD, or network.
///
///
///
/// The MsiSetComponentState function returns the following values:
///
/// The MsiSetComponentState function requests a change in the Action state of a record in the Component table.
/// For more information, see Calling Database Functions From Programs.
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msisetcomponentstatea UINT MsiSetComponentStateA(
// MSIHANDLE hInstall, LPCSTR szComponent, INSTALLSTATE iState );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiSetComponentStateA")]
public static extern Win32Error MsiSetComponentState(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szComponent, INSTALLSTATE iState);
///
/// The MsiSetFeatureAttributes function can modify the default attributes of a feature at runtime. Note that the default
/// attributes of features are authored in the Attributes column of the Feature table.
///
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
/// Specifies the feature name within the product.
///
/// Feature attributes specified at run time as a set of bit flags:
///
///
/// Constant
/// Meaning
///
/// -
/// INSTALLFEATUREATTRIBUTE_FAVORLOCAL 1
///
/// Modifies default feature attributes to msidbFeatureAttributesFavorLocal at run time. See Attributes column of the Feature table
/// for a description.
///
///
/// -
/// INSTALLFEATUREATTRIBUTE_FAVORSOURCE 2
///
/// Modifies default feature attributes to msidbFeatureAttributesFavorSource at run time. See Attributes column of the Feature table
/// for a description.
///
///
/// -
/// INSTALLFEATUREATTRIBUTE_FOLLOWPARENT 4
///
/// Modifies default feature attributes to msidbFeatureAttributesFollowParent at run time. Note that this is not a valid attribute
/// to be set for top-level features. See Attributes column of the Feature table for a description.
///
///
/// -
/// INSTALLFEATUREATTRIBUTE_FAVORADVERTISE 8
///
/// Modifies default feature attributes to msidbFeatureAttributesFavorAdvertise at run time. See Attributes column of the Feature
/// table for a description.
///
///
/// -
/// INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE 16
///
/// Modifies default feature attributes to msidbFeatureAttributesDisallowAdvertise at run time. See Attributes column of the Feature
/// table for a description.
///
///
/// -
/// INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE 32
///
/// Modifies default feature attributes to msidbFeatureAttributesNoUnsupportedAdvertise at run time. See Attributes column of the
/// Feature table for a description.
///
///
///
///
/// This function returns UINT.
///
///
/// MsiSetFeatureAttributes must be called after CostInitialize action and before CostFinalize action. The function returns
/// ERROR_FUNCTION_FAILED if called at any other time.
///
///
/// The INSTALLFEATUREATTRIBUTE_FAVORLOCAL, INSTALLFEATUREATTRIBUTE_FAVORSOURCE, and INSTALLFEATUREATTRIBUTE_FOLLOWPARENT flags are
/// mutually exclusive. Only one of these bits can be set for any feature. If more than one of these flags is set, the behavior of
/// that feature is undefined.
///
/// See Calling Database Functions From Programs.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msisetfeatureattributesa UINT MsiSetFeatureAttributesA(
// MSIHANDLE hInstall, LPCSTR szFeature, DWORD dwAttributes );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiSetFeatureAttributesA")]
public static extern Win32Error MsiSetFeatureAttributes(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szFeature, INSTALLFEATUREATTRIBUTE dwAttributes);
/// The MsiSetFeatureState function sets a feature to a specified state.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
/// Specifies the name of the feature.
///
/// Specifies the state to set. This parameter can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// INSTALLSTATE_ABSENT
/// The feature is not installed.
///
/// -
/// INSTALLSTATE_LOCAL
/// The feature is installed on the local drive.
///
/// -
/// INSTALLSTATE_SOURCE
/// The feature is run from the source, CD, or network.
///
/// -
/// INSTALLSTATE_ADVERTISED
/// The feature is advertised.
///
///
///
/// The MsiSetFeatureState function returns the following values:
///
///
/// The MsiSetFeatureState function requests a change in the select state of a feature in the Feature table and its children.
/// In turn, the action state of all the components linked to the changed feature records are also updated appropriately, based on
/// the new feature select state.
///
/// The MsiSetInstallLevel function must be called before calling MsiSetFeatureState.
///
/// When MsiSetFeatureState is called, the installer attempts to set the action state of each component tied to the specified
/// feature to the specified state. However, there are common situations when the request cannot be fully implemented. For example,
/// if a feature is tied to two components, component A and component B, through the FeatureComponents table, and component A has
/// the msidbComponentAttributesLocalOnly attribute and component B has the msidbComponentAttributesSourceOnly
/// attribute. In this case, if MsiSetFeatureState is called with a requested state of either INSTALLSTATE_LOCAL or
/// INSTALLSTATE_SOURCE, the request cannot be fully implemented for both components. In this case, both components are turned ON,
/// with component A set to Local and component B set to Source.
///
///
/// If more than one feature is linked to a single component (a common scenario), the final action state of that component is
/// determined as follows:
///
///
/// -
/// If at least one feature requires the component to be installed locally, the feature is installed with a state of local.
///
/// -
/// If at least one feature requires the component to be run from the source, the feature is installed with a state of source.
///
/// -
/// If at least one feature requires the removal of the component, the action state is absent.
///
///
/// See Calling Database Functions from Programs.
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msisetfeaturestatea UINT MsiSetFeatureStateA( MSIHANDLE
// hInstall, LPCSTR szFeature, INSTALLSTATE iState );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiSetFeatureStateA")]
public static extern Win32Error MsiSetFeatureState(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szFeature, INSTALLSTATE iState);
/// The MsiSetInstallLevel function sets the installation level for a full product installation.
///
/// Handle to the installation that is provided to a DLL custom action or obtained by using MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
/// The installation level.
/// The MsiSetInstallLevel function returns one of the following values:
///
/// The MsiSetInstallLevel function sets the following:
///
/// -
/// The installation level for the current installation to a specified value.
///
/// -
/// The Select and Installed states for all features in the Feature table.
///
/// -
/// The Action state of each component in the Component table, based on the new level.
///
///
///
/// For any installation, there is a defined install level, which is an integral value from 1 to 32,767. The initial value is
/// determined by the INSTALLLEVEL property, which is set in the Property Table.
///
///
/// If 0 (zero) or a negative number is passed in the iInstallLevel parameter, the current installation level does not change, but
/// all features are still updated based on the current installation level. For more information, see Calling Database Functions
/// From Programs.
///
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msisetinstalllevel UINT MsiSetInstallLevel( MSIHANDLE
// hInstall, int iInstallLevel );
[DllImport(Lib_Msi, SetLastError = true, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiSetInstallLevel")]
public static extern Win32Error MsiSetInstallLevel(MSIHANDLE hInstall, int iInstallLevel);
/// The MsiSetMode function sets an internal engine Boolean state.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
///
///
/// Specifies the run mode. This parameter must be one of the following values. While there are many values for this parameter, as
/// described in MsiGetMode, only one of the following values can be set.
///
///
///
/// Value
/// Meaning
///
/// -
/// MSIRUNMODE_REBOOTATEND
/// A reboot is necessary after a successful installation.
///
/// -
/// MSIRUNMODE_REBOOTNOW
/// A reboot is necessary to continue installation.
///
///
///
/// Specifies the state to set to TRUE or FALSE.
/// This function returns UINT.
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msisetmode UINT MsiSetMode( MSIHANDLE hInstall,
// MSIRUNMODE eRunMode, BOOL fState );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiSetMode")]
public static extern Win32Error MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE eRunMode, [MarshalAs(UnmanagedType.Bool)] bool fState);
/// The MsiSetProperty function sets the value for an installation property.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
/// Specifies the name of the property.
/// Specifies the value of the property.
/// This function returns UINT.
///
/// If the property is not defined, it is created by the MsiSetProperty function. If the value is null or an empty string,
/// the property is removed.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msisetpropertya UINT MsiSetPropertyA( MSIHANDLE hInstall,
// LPCSTR szName, LPCSTR szValue );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiSetPropertyA")]
public static extern Win32Error MsiSetProperty(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szName,
[Optional, MarshalAs(UnmanagedType.LPTStr)] string szValue);
/// The MsiSetTargetPath function sets the full target path for a folder in the Directory table.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
/// Specifies the folder identifier. This is a primary key in the Directory table.
/// Specifies the full path for the folder, ending in a directory separator.
/// The MsiSetTargetPath function returns the following values:
///
///
/// The MsiSetTargetPath function changes the path specification for the target directory named in the in-memory Directory
/// table. Also, the path specifications of all other path objects in the table that are either subordinate or equivalent to the
/// changed path are updated to reflect the change. The properties for each affected path are also updated.
///
/// MsiSetTargetPath fails if the selected directory is read only.
///
/// If an error occurs in this function, all updated paths and properties revert to their previous values. Therefore, it is safe to
/// treat errors returned by this function as nonfatal.
///
///
/// Do not attempt to configure the target path if the components using those paths are already installed for the current user or
/// for a different user. Check the ProductState property before calling MsiSetTargetPath to determine if the product
/// containing this component is installed.
///
/// See Calling Database Functions From Programs.
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msisettargetpatha UINT MsiSetTargetPathA( MSIHANDLE
// hInstall, LPCSTR szFolder, LPCSTR szFolderPath );
[DllImport(Lib_Msi, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiSetTargetPathA")]
public static extern Win32Error MsiSetTargetPath(MSIHANDLE hInstall, [MarshalAs(UnmanagedType.LPTStr)] string szFolder,
[MarshalAs(UnmanagedType.LPTStr)] string szFolderPath);
///
/// The MsiSummaryInfoGetProperty function gets a single property from the summary information stream.
///
/// Note The meaning of the property value depends on whether the summary information stream is for an installation database
/// (.msi file), transform (.mst file) or patch (.msp file). See Summary Property Descriptions and Summary Information Stream
/// Property Set for more information about summary information properties.
///
///
/// Handle to summary information.
///
/// Specifies the property ID of the summary property. This parameter can be a property ID listed in the Summary Information Stream
/// Property Set. This function does not return values for PID_DICTIONARY OR PID_THUMBNAIL property.
///
///
/// Receives the returned property type. This parameter can be a type listed in the Summary Information Stream Property Set.
///
/// Receives the returned integer property data.
/// Pointer to a file value.
///
/// Pointer to the buffer that receives the null terminated summary information property value. Do not attempt to determine the size
/// of the buffer by passing in a null (value=0) for szValueBuf. You can get the size of the buffer by passing in an empty string
/// (for example ""). The function then returns ERROR_MORE_DATA and pcchValueBuf contains the required buffer size in TCHARs,
/// not including the terminating null character. On return of ERROR_SUCCESS, pcchValueBuf contains the number of TCHARs
/// written to the buffer, not including the terminating null character. This parameter is an empty string if there are no errors.
///
///
/// Pointer to the variable that specifies the size, in TCHARs, of the buffer pointed to by the variable szValueBuf. When the
/// function returns ERROR_SUCCESS, this variable contains the size of the data copied to szValueBuf, not including the terminating
/// null character. If szValueBuf is not large enough, the function returns ERROR_MORE_DATA and stores the required size, not
/// including the terminating null character, in the variable pointed to by pcchValueBuf.
///
/// The MsiSummaryInfoGetProperty function returns one of the following values:
///
///
/// If ERROR_MORE_DATA is returned, the parameter which is a pointer gives the size of the buffer required to hold the string. If
/// ERROR_SUCCESS is returned, it gives the number of characters written to the string buffer. Therefore you can get the size of the
/// buffer by passing in an empty string (for example "") for the parameter that specifies the buffer. Do not attempt to determine
/// the size of the buffer by passing in a Null (value=0).
///
///
/// Windows Installer functions that return data in a user provided memory location should not be called with null as the value for
/// the pointer. These functions return a string or return data as integer pointers, but return inconsistent values when passing
/// null as the value for the output argument. For more information, see Passing Null as the Argument of Windows Installer Functions.
///
///
/// The property information returned by the MsiSummaryInfoGetProperty function is received by the piValue, pftValue, or
/// szValueBuf parameter depending upon the type of property value that has been specified in the puiDataType parameter.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msisummaryinfogetpropertya UINT
// MsiSummaryInfoGetPropertyA( MSIHANDLE hSummaryInfo, UINT uiProperty, PUINT puiDataType, LPINT piValue, FILETIME *pftValue, LPSTR
// szValueBuf, LPDWORD pcchValueBuf );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiSummaryInfoGetPropertyA")]
public static extern Win32Error MsiSummaryInfoGetProperty(MSIHANDLE hSummaryInfo, uint uiProperty, out uint puiDataType, out int piValue,
out FILETIME pftValue, [Out, Optional, MarshalAs(UnmanagedType.LPTStr)] StringBuilder szValueBuf, ref uint pcchValueBuf);
///
/// The MsiSummaryInfoGetPropertyCount function returns the number of existing properties in the summary information stream.
///
/// Handle to summary information.
/// Location to receive the total property count.
/// This function returns UINT.
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msisummaryinfogetpropertycount UINT
// MsiSummaryInfoGetPropertyCount( MSIHANDLE hSummaryInfo, PUINT puiPropertyCount );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiSummaryInfoGetPropertyCount")]
public static extern Win32Error MsiSummaryInfoGetPropertyCount(MSIHANDLE hSummaryInfo, out uint puiPropertyCount);
/// The MsiSummaryInfoPersist function writes changed summary information back to the summary information stream.
/// Handle to summary information.
/// This function returns UINT.
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msisummaryinfopersist UINT MsiSummaryInfoPersist(
// MSIHANDLE hSummaryInfo );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiSummaryInfoPersist")]
public static extern Win32Error MsiSummaryInfoPersist(MSIHANDLE hSummaryInfo);
///
/// The MsiSummaryInfoSetProperty function sets a single summary information property.
///
/// Note The meaning of the property value depends on whether the summary information stream is for an installation database
/// (.msi file), transform (.mst file) or patch (.msp file). See Summary Property Descriptions and Summary Information Stream
/// Property Set for more information about summary information properties.
///
///
/// Handle to summary information.
///
/// Specifies the property ID of the summary property being set. This parameter can be a property ID listed in the Summary
/// Information Stream Property Set. This function does not set values for PID_DICTIONARY OR PID_THUMBNAIL property.
///
///
/// Specifies the type of property to set. This parameter can be a type listed in the Summary Information Stream Property Set.
///
/// Specifies the integer value.
/// Specifies the file-time value.
/// Specifies the text value.
/// The MsiSummaryInfoSetProperty function returns the following values:
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msisummaryinfosetpropertya UINT
// MsiSummaryInfoSetPropertyA( MSIHANDLE hSummaryInfo, UINT uiProperty, UINT uiDataType, INT iValue, FILETIME *pftValue, LPCSTR
// szValue );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiSummaryInfoSetPropertyA")]
public static extern Win32Error MsiSummaryInfoSetProperty(MSIHANDLE hSummaryInfo, uint uiProperty, uint uiDataType, [Optional] int iValue,
in FILETIME pftValue, [Optional, MarshalAs(UnmanagedType.LPTStr)] string szValue);
///
/// The MsiSummaryInfoSetProperty function sets a single summary information property.
///
/// Note The meaning of the property value depends on whether the summary information stream is for an installation database
/// (.msi file), transform (.mst file) or patch (.msp file). See Summary Property Descriptions and Summary Information Stream
/// Property Set for more information about summary information properties.
///
///
/// Handle to summary information.
///
/// Specifies the property ID of the summary property being set. This parameter can be a property ID listed in the Summary
/// Information Stream Property Set. This function does not set values for PID_DICTIONARY OR PID_THUMBNAIL property.
///
///
/// Specifies the type of property to set. This parameter can be a type listed in the Summary Information Stream Property Set.
///
/// Specifies the integer value.
/// Specifies the file-time value.
/// Specifies the text value.
/// The MsiSummaryInfoSetProperty function returns the following values:
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msisummaryinfosetpropertya UINT
// MsiSummaryInfoSetPropertyA( MSIHANDLE hSummaryInfo, UINT uiProperty, UINT uiDataType, INT iValue, FILETIME *pftValue, LPCSTR
// szValue );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiSummaryInfoSetPropertyA")]
public static extern Win32Error MsiSummaryInfoSetProperty(MSIHANDLE hSummaryInfo, uint uiProperty, uint uiDataType, [Optional] int iValue,
[In, Optional] IntPtr pftValue, [Optional, MarshalAs(UnmanagedType.LPTStr)] string szValue);
/// The MsiVerifyDiskSpace function checks to see if sufficient disk space is present for the current installation.
///
/// Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.
///
/// This function returns UINT.
/// See Calling Database Functions From Programs.
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msiverifydiskspace UINT MsiVerifyDiskSpace( MSIHANDLE
// hInstall );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiVerifyDiskSpace")]
public static extern Win32Error MsiVerifyDiskSpace(MSIHANDLE hInstall);
/// The MsiViewClose function releases the result set for an executed view.
/// Handle to a view that is set to release.
/// Note that in low memory situations, this function can raise a STATUS_NO_MEMORY exception.
///
/// The MsiViewClose function must be called before the MsiViewExecute function is called again on the view, unless all rows
/// of the result set have been obtained with the MsiViewFetch function.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msiviewclose UINT MsiViewClose( MSIHANDLE hView );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiViewClose")]
public static extern Win32Error MsiViewClose(MSIHANDLE hView);
///
/// The MsiViewExecute function executes a SQL view query and supplies any required parameters. The query uses the question
/// mark token to represent parameters as described in SQL Syntax. The values of these parameters are passed in as the corresponding
/// fields of a parameter record.
///
/// Handle to the view upon which to execute the query.
///
/// Handle to a record that supplies the parameters. This parameter contains values to replace the parameter tokens in the SQL
/// query. It is optional, so hRecord can be zero. For a reference on syntax, see SQL Syntax.
///
/// Note that in low memory situations, this function can raise a STATUS_NO_MEMORY exception.
///
/// The MsiViewExecute function must be called before any calls to MsiViewFetch.
///
/// If the SQL query specifies values with parameter markers (?), a record must be supplied that contains all of the replacement
/// values in the exact order and of compatible data types. When used with INSERT and UPDATE queries all the parameterized values
/// must precede all nonparameterized values.
///
/// For example, these queries are valid.
/// UPDATE {table-list} SET {column}= ? , {column}= {constant}
/// INSERT INTO {table} ({column-list}) VALUES (?, {constant-list})
/// However these queries are invalid.
/// UPDATE {table-list} SET {column}= {constant}, {column}=?
/// INSERT INTO {table} ({column-list}) VALUES ({constant-list}, ? )
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msiviewexecute UINT MsiViewExecute( MSIHANDLE hView,
// MSIHANDLE hRecord );
[DllImport(Lib_Msi, SetLastError = true, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiViewExecute")]
public static extern Win32Error MsiViewExecute(MSIHANDLE hView, [Optional] MSIHANDLE hRecord);
///
/// The MsiViewFetch function fetches the next sequential record from the view. This function returns a handle that should be
/// closed using MsiCloseHandle.
///
/// Handle to the view to fetch from.
/// Pointer to the handle for the fetched record.
/// Note that in low memory situations, this function can raise a STATUS_NO_MEMORY exception.
///
///
/// If the MsiViewFetch function returns ERROR_FUNCTION_FAILED, it is possible that the MsiViewExecute function was not
/// called first. If more rows are available in the result set, MsiViewFetch returns phRecord as a handle to a record
/// containing the requested column data, or phRecord is 0. For maximum performance, the same record should be used for all
/// retrievals, or the record should be released by going out of scope.
///
///
/// Note that it is recommended to use variables of type PMSIHANDLE because the installer closes PMSIHANDLE objects as they go out
/// of scope, whereas you must close MSIHANDLE objects by calling MsiCloseHandle. For more information see Use PMSIHANDLE instead of
/// HANDLE section in the Windows Installer Best Practices.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msiviewfetch UINT MsiViewFetch( MSIHANDLE hView,
// MSIHANDLE *phRecord );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiViewFetch")]
public static extern Win32Error MsiViewFetch(MSIHANDLE hView, out PMSIHANDLE phRecord);
///
/// The MsiViewGetColumnInfo function returns a record containing column names or definitions. This function returns a handle
/// that should be closed using MsiCloseHandle.
///
/// Handle to the view from which to obtain column information.
///
/// Specifies a flag indicating what type of information is needed. This parameter must be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// MSICOLINFO_NAMES
/// Column names are returned.
///
/// -
/// MSICOLINFO_TYPES
/// Definitions are returned.
///
///
///
/// Pointer to a handle to receive the column information data record.
/// Note that in low memory situations, this function can raise a STATUS_NO_MEMORY exception.
///
///
/// The column description returned by MsiViewGetColumnInfo is in the format described in the section: Column Definition
/// Format. Each column is described by a string in the corresponding record field. The definition string consists of a single
/// letter representing the data type followed by the width of the column (in characters when applicable, bytes otherwise). A width
/// of zero designates an unbounded width (for example, long text fields and streams). An uppercase letter indicates that null
/// values are allowed in the column.
///
///
/// Note that it is recommended to use variables of type PMSIHANDLE because the installer closes PMSIHANDLE objects as they go out
/// of scope, whereas you must close MSIHANDLE objects by calling MsiCloseHandle. For more information see Use PMSIHANDLE instead of
/// HANDLE section in the Windows Installer Best Practices.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msiviewgetcolumninfo UINT MsiViewGetColumnInfo( MSIHANDLE
// hView, MSICOLINFO eColumnInfo, MSIHANDLE *phRecord );
[DllImport(Lib_Msi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiViewGetColumnInfo")]
public static extern Win32Error MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO eColumnInfo, out PMSIHANDLE phRecord);
/// The MsiViewGetError function returns the error that occurred in the MsiViewModify function.
/// Handle to the view.
///
/// Pointer to the buffer that receives the null-terminated column name. Do not attempt to determine the size of the buffer by
/// passing in a null (value=0) for szColumnName. You can get the size of the buffer by passing in an empty string (for example "").
/// The function then returns MSIDBERROR_MOREDATA and pcchBuf contains the required buffer size in TCHARs, not including the
/// terminating null character. On return of MSIDBERROR_NOERROR, pcchBuf contains the number of TCHARs written to the buffer, not
/// including the terminating null character. This parameter is an empty string if there are no errors.
///
///
/// Pointer to the variable that specifies the size, in TCHARs, of the buffer pointed to by the variable szColumnNameBuffer. When
/// the function returns MSIDBERROR_NOERROR, this variable contains the size of the data copied to szColumnNameBuffer, not including
/// the terminating null character. If szColumnNameBuffer is not large enough, the function returns MSIDBERROR_MOREDATA and stores
/// the required size, not including the terminating null character, in the variable pointed to by pcchBuf.
///
///
/// This function returns one of the following values.
///
///
/// Error code
/// Meaning
///
/// -
/// MSIDBERROR_INVALIDARG
/// An argument was invalid.
///
/// -
/// MSIDBERROR_MOREDATA
/// The buffer was too small to receive data.
///
/// -
/// MSIDBERROR_FUNCTIONERROR
/// The function failed.
///
/// -
/// MSIDBERROR_NOERROR
/// The function completed successfully with no errors.
///
/// -
/// MSIDBERROR_DUPLICATEKEY
/// The new record duplicates primary keys of the existing record in a table.
///
/// -
/// MSIDBERROR_REQUIRED
/// There are no null values allowed; or the column is about to be deleted, but is referenced by another row.
///
/// -
/// MSIDBERROR_BADLINK
/// The corresponding record in a foreign table was not found.
///
/// -
/// MSIDBERROR_OVERFLOW
/// The data is greater than the maximum value allowed.
///
/// -
/// MSIDBERROR_UNDERFLOW
/// The data is less than the minimum value allowed.
///
/// -
/// MSIDBERROR_NOTINSET
/// The data is not a member of the values permitted in the set.
///
/// -
/// MSIDBERROR_BADVERSION
/// An invalid version string was supplied.
///
/// -
/// MSIDBERROR_BADCASE
/// The case was invalid. The case must be all uppercase or all lowercase.
///
/// -
/// MSIDBERROR_BADGUID
/// An invalid GUID was supplied.
///
/// -
/// MSIDBERROR_BADWILDCARD
/// An invalid wildcard file name was supplied, or the use of wildcards was invalid.
///
/// -
/// MSIDBERROR_BADIDENTIFIER
/// An invalid identifier was supplied.
///
/// -
/// MSIDBERROR_BADLANGUAGE
/// Invalid language IDs were supplied.
///
/// -
/// MSIDBERROR_BADFILENAME
/// An invalid file name was supplied.
///
/// -
/// MSIDBERROR_BADPATH
/// An invalid path was supplied.
///
/// -
/// MSIDBERROR_BADCONDITION
/// An invalid conditional statement was supplied.
///
/// -
/// MSIDBERROR_BADFORMATTED
/// An invalid format string was supplied.
///
/// -
/// MSIDBERROR_BADTEMPLATE
/// An invalid template string was supplied.
///
/// -
/// MSIDBERROR_BADDEFAULTDIR
/// An invalid string was supplied in the DefaultDir column of the Directory table.
///
/// -
/// MSIDBERROR_BADREGPATH
/// An invalid registry path string was supplied.
///
/// -
/// MSIDBERROR_BADCUSTOMSOURCE
/// An invalid string was supplied in the CustomSource column of the CustomAction table.
///
/// -
/// MSIDBERROR_BADPROPERTY
/// An invalid property string was supplied.
///
/// -
/// MSIDBERROR_MISSINGDATA
/// The _Validation table is missing a reference to a column.
///
/// -
/// MSIDBERROR_BADCATEGORY
/// The category column of the _Validation table for the column is invalid.
///
/// -
/// MSIDBERROR_BADCABINET
/// An invalid cabinet name was supplied.
///
/// -
/// MSIDBERROR_BADKEYTABLE
/// The table in the Keytable column of the _Validation table was not found or loaded.
///
/// -
/// MSIDBERROR_BADMAXMINVALUES
/// The value in the MaxValue column of the _Validation table is less than the value in the MinValue column.
///
/// -
/// MSIDBERROR_BADSHORTCUT
/// An invalid shortcut target name was supplied.
///
/// -
/// MSIDBERROR_STRINGOVERFLOW
/// The string is too long for the length specified by the column definition.
///
/// -
/// MSIDBERROR_BADLOCALIZEATTRIB
/// An invalid localization attribute was supplied. (Primary keys cannot be localized.)
///
///
/// Note that in low memory situations, this function can raise a STATUS_NO_MEMORY exception.
///
///
///
/// You should only call the MsiViewGetError function when MsiViewModify returns ERROR_INVALID_DATA, indicating that the data
/// is invalid. Errors are only recorded for MSIMODIFY_VALIDATE, MSIMODIFY_VALIDATE_NEW, and MSIMODIFY_VALIDATEFIELD.
///
///
/// If ERROR_MORE_DATA is returned, the parameter that is a pointer gives the size of the buffer required to hold the string. Upon
/// success, it gives the number of characters written to the string buffer. Therefore you can get the required size of the buffer
/// by passing a small buffer (one character minimum) and examining the value at pcchPathBuf when the function returns
/// MSIDBERROR_MOREDATA. Do not attempt to determine the size of the buffer by passing in null as szColumnNameBuffer or a buffer
/// size of 0 in the DWORD referenced by pcchBuf.
///
///
/// Once MSIDBERROR_NOERROR is returned, no more validation errors remain. The MSIDBERROR return value indicates the type of
/// validation error that occurred for the value located in the column identified by the szColumnNameBuffer.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msiviewgeterrorw MSIDBERROR MsiViewGetErrorW( MSIHANDLE
// hView, LPWSTR szColumnNameBuffer, LPDWORD pcchBuf );
[DllImport(Lib_Msi, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiViewGetErrorW")]
public static extern MSIDBERROR MsiViewGetError(MSIHANDLE hView, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder szColumnNameBuffer, ref uint pcchBuf);
/// The MsiViewModify function updates a fetched record.
/// Handle to a view.
///
/// Specifies the modify mode. This parameter can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// MSIMODIFY_SEEK -1
///
/// Refreshes the information in the supplied record without changing the position in the result set and without affecting
/// subsequent fetch operations. The record may then be used for subsequent Update, Delete, and Refresh. All primary key columns of
/// the table must be in the query and the record must have at least as many fields as the query. Seek cannot be used with
/// multi-table queries. This mode cannot be used with a view containing joins. See also the remarks.
///
///
/// -
/// MSIMODIFY_REFRESH 0
///
/// Refreshes the information in the record. Must first call MsiViewFetch with the same record. Fails for a deleted row. Works with
/// read-write and read-only records.
///
///
/// -
/// MSIMODIFY_INSERT 1
///
/// Inserts a record. Fails if a row with the same primary keys exists. Fails with a read-only database. This mode cannot be used
/// with a view containing joins.
///
///
/// -
/// MSIMODIFY_UPDATE 2
///
/// Updates an existing record. Nonprimary keys only. Must first call MsiViewFetch. Fails with a deleted record. Works only with
/// read-write records.
///
///
/// -
/// MSIMODIFY_ASSIGN 3
///
/// Writes current data in the cursor to a table row. Updates record if the primary keys match an existing row and inserts if they
/// do not match. Fails with a read-only database. This mode cannot be used with a view containing joins.
///
///
/// -
/// MSIMODIFY_REPLACE 4
///
/// Updates or deletes and inserts a record into a table. Must first call MsiViewFetch with the same record. Updates record if the
/// primary keys are unchanged. Deletes old row and inserts new if primary keys have changed. Fails with a read-only database. This
/// mode cannot be used with a view containing joins.
///
///
/// -
/// MSIMODIFY_MERGE 5
///
/// Inserts or validates a record in a table. Inserts if primary keys do not match any row and validates if there is a match. Fails
/// if the record does not match the data in the table. Fails if there is a record with a duplicate key that is not identical. Works
/// only with read-write records. This mode cannot be used with a view containing joins.
///
///
/// -
/// MSIMODIFY_DELETE 6
///
/// Remove a row from the table. You must first call the MsiViewFetch function with the same record. Fails if the row has been
/// deleted. Works only with read-write records. This mode cannot be used with a view containing joins.
///
///
/// -
/// MSIMODIFY_INSERT_TEMPORARY 7
///
/// Inserts a temporary record. The information is not persistent. Fails if a row with the same primary key exists. Works only with
/// read-write records. This mode cannot be used with a view containing joins.
///
///
/// -
/// MSIMODIFY_VALIDATE 8
///
/// Validates a record. Does not validate across joins. You must first call the MsiViewFetch function with the same record. Obtain
/// validation errors with MsiViewGetError. Works with read-write and read-only records. This mode cannot be used with a view
/// containing joins.
///
///
/// -
/// MSIMODIFY_VALIDATE_NEW 9
///
/// Validate a new record. Does not validate across joins. Checks for duplicate keys. Obtain validation errors by calling
/// MsiViewGetError. Works with read-write and read-only records. This mode cannot be used with a view containing joins.
///
///
/// -
/// MSIMODIFY_VALIDATE_FIELD 10
///
/// Validates fields of a fetched or new record. Can validate one or more fields of an incomplete record. Obtain validation errors
/// by calling MsiViewGetError. Works with read-write and read-only records. This mode cannot be used with a view containing joins.
///
///
/// -
/// MSIMODIFY_VALIDATE_DELETE 11
///
/// Validates a record that will be deleted later. You must first call MsiViewFetch. Fails if another row refers to the primary keys
/// of this row. Validation does not check for the existence of the primary keys of this row in properties or strings. Does not
/// check if a column is a foreign key to multiple tables. Obtain validation errors by calling MsiViewGetError. Works with
/// read-write and read-only records. This mode cannot be used with a view that contains joins.
///
///
///
///
/// Handle to the record to modify.
///
/// The MsiViewModify function returns the following values:
/// Note that in low memory situations, this function can raise a STATUS_NO_MEMORY exception.
///
///
///
/// The MSIMODIFY_VALIDATE, MSIMODIFY_VALIDATE_NEW, MSIMODIFY_VALIDATE_FIELD, and MSIMODIFY_VALIDATE_DELETE values of the
/// MsiViewModify function do not perform actual updates; they ensure that the data in the record is valid. Use of these
/// validation enumerations requires that the database contains the _Validation table.
///
///
/// You can call MSIMODIFY_UPDATE or MSIMODIFY_DELETE with a record immediately after using MSIMODIFY_INSERT,
/// MSIMODIFY_INSERT_TEMPORARY, or MSIMODIFY_SEEK provided you have NOT modified the 0th field of the inserted or sought record.
///
///
/// To execute any SQL statement, a view must be created. However, a view that does not create a result set, such as CREATE TABLE,
/// or INSERT INTO, cannot be used with MsiViewModify to update tables though the view.
///
///
/// You cannot fetch a record that contains binary data from one database and then use that record to insert the data into another
/// database. To move binary data from one database to another, you should export the data to a file and then import it into the new
/// database using a query and the MsiRecordSetStream. This ensures that each database has its own copy of the binary data.
///
///
/// Note that custom actions can only add, modify, or remove temporary rows, columns, or tables from a database. Custom actions
/// cannot modify persistent data in a database, such as data that is a part of the database stored on disk. For more information,
/// see Accessing the Current Installer Session from Inside a Custom Action.
///
/// If the function fails, you can obtain extended error information by using MsiGetLastErrorRecord.
///
// https://docs.microsoft.com/en-us/windows/win32/api/msiquery/nf-msiquery-msiviewmodify UINT MsiViewModify( MSIHANDLE hView,
// MSIMODIFY eModifyMode, MSIHANDLE hRecord );
[DllImport(Lib_Msi, SetLastError = true, ExactSpelling = true)]
[PInvokeData("msiquery.h", MSDNShortId = "NF:msiquery.MsiViewModify")]
public static extern Win32Error MsiViewModify(MSIHANDLE hView, MSIMODIFY eModifyMode, MSIHANDLE hRecord);
}
}