#$KInstaller Development Tools
THESE TOOLS AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
MsiDb - database import, export, merge, transform
MsiMsp - patch package creation
MsiInfo - summary information property manager, string pool validation
MsiMerg - merges one database into another
MsiTran - generates and applies transforms
Orca - package editing/creation tool
MsiVal2 - command line ICE validation tool.
Msispy  - installer registration browser
MsiZap  - failure cleanup utility
Makefile - makefile used to build custom actions and tools

#$K+MSIDB.EXE Tool To Modify A Database
The MSIDB.EXE tool uses the MSI database external API to import and export database tables and streams, merge databases and apply transforms to databases.  It is essentially a UI and/or command line processing layer on top of the MsiDatabaseImport and MsiDatabaseExport Windows Installer APIs.  If all required parameters (mode, folder, database and table list) are specified on the command line, the tool will not bring up any UI and will operate as silent command line-driven utility, suitable for a build script. If the folder containing the text archive files is not specified it will be prompted for; likewise the database will  be prompted for if not specified. Tables can be exported from a read only database.
Command Line Syntax
MsiDb {option}...{option}... {table}...{table}
The following case-insensitive command line options are supported (slash delimiter may also be used).
 -i    Import text archive files from folder into specified database
 -e    Export selected tables into text archive files in specified folder
 -c    Creates a new database file (overwrites existing) and imports tables
 -f    Specifies the folder containing the text archive files for tables and streams
 -d    Fully-qualified path to the database
 -m    Fully-qualified path to the database to merge in
 -t    Fully-qualified path to the transform to apply
 -j    Name of storage to remove from the database.
 -k    Name of stream to remove from the database.
 -x    Name of stream to save to a disk file in the current directory.
 -w    Name of storage to save to a disk file in the current directory.
 -a    Name of file to add to the database (becomes a child stream).
 -r    Name of storage to add to the database (becomes a substorage).
 -s    Truncate table names to 8 chars on idt export.
 -?    Displays command line help dialog
Table names for import are file names. Standard wild card specifications may be used.
Table names for export are table names. Only the wildcard specification, "*", may be used.
Multiple -m's, -a's, -r's, -t's, -j's, -k's, -w's, and -x's may be used (maximum of 10 each).
The -m, -a, -r, -t, -j, -k, -w, and -x options are only available in silent command line mode.
Archive Table Naming
Only archive text files with the ".idt" extension may be imported.
The table name is truncated to 8 characters if -s is used, and the extension ".idt" added.
Tables names supplied by command for import are likewise converted.
The name used for database table creation is maintained in the .idt file.
Binary data streams are stored as separate files with extension ".ibd".
Binary filename used is primary key data for the row containing the stream.

Note:  When using long filenames with spaces, use quotes around them.  For example, for a database that is in the 'My Documents' folder, specify it as "c:\my documents".
#$K+MSIMSP.EXE Tool To Create Patch Packages
The MSIMSP.EXE tool is a wrapper for PatchWiz.dll.  The tool may be used to create a patch package by passing in the path to a "Patch Creation Properties" file or PCP file, and the path to the patch package to create. Additional options include creating a log file, and specifying a non-default temporary folder in which the transforms, cabinets and assorted files used to create the patch package are left behind.  See msi.chm for more info on setting up a Patch Creation Properties file, as well as meanings of error codes from PatchWiz.dll and MSIMSP.EXE.
Command Line Syntax
MsiMsp {option}...{option}...
The following case-insensitive command line options are supported (slash delimiter may also be used).
 -s    Required.  Followed by path to Patch Creation Properties file.
 -p    Required.  Followed by path to patch package to create.
 -f    Optional.  Followed by path to temporary folder.
 -k    Optional.  Fail if temporary folder already exists.
 -l    Optional.  Followed by path to log file describing patch creation process and errors.
 -d    Optional.  Will display dialog if and when patch creation has completed successfully.
 -?    Displays command line help dialog

Note:  When using long filenames with spaces, use quotes around them.  For example, for a Patch Creation Project that is in the 'My Documents' folder, specify it as "c:\My Documents".
#$K+MSIINFO.EXE Tool To Modify A Database's Summary Properties
The MSIINFO.EXE tool uses the MSI database external API to edit or display the summary information of a database. It is a command line tool.
Command Line Syntax
MsiInfo {database} [[/B] /D]
Displays the Summary information of the database to the console

The following case-insensitive command line options are supported (slash delimiter may also be used).
 -B     Display information about every string in the string pool.
 -D     Display information about the string pool.

Remarks
The -D option will examine the string pool for corruption and provide information about the codepage of the database.  Note that the codepage of the database is different from the codepage of the Summary Information stream (PID_CODEPAGE). It will also check every string for characters that are invalid in the codepage of the database. The -B option is only valid if -D is also used, and it must come before the -D option.

MsiInfo {database} {option} {data}.....
Sets the corresponding summary information property

The following case-insensitive command line options are supported (slash delimiter may also be used).
 -I     PID_DICTIONARY
 -C     PID_CODEPAGE
 -T     PID_TITLE
 -J     PID_SUBJECT
 -A     PID_AUTHOR
 -K     PID_KEYWORDS
 -O     PID_COMMENTS
 -P     PID_TEMPLATE
 -L     PID_LASTAUTHOR
 -V     PID_REVNUMBER
 -E     PID_EDITTIME
 -S     PID_LASTPRINTED
 -R     PID_CREATE_DTM
 -Q     PID_LASTSAVE_DTM
 -G     PID_PAGECOUNT
 -W     PID_WORDCOUNT
 -H     PID_CHARCOUNT
        PID_THUMBNAIL     !! NOT SUPPORTED !!
 -N     PID_APPNAME
 -U     PID_SECURITY

The data following the option is optional. If there is no data following the option, then the property is removed. The database must not be a readOnly database.  The same properties can be specified again on the command line, but only 20 switches can be used.  If the data for a particular option contains a space, encapsulate it in quotes, such as /T "MY TITLE".  The quotation marks notify the command line parser to ignore the space.  For the file time  properties, those being PID_EDITTIME, PID_LASTPRINTED, PID_CREATE_DTM, and PID_LASTSAVE_DTM, use the following format "year/month/day hour:minute:second" which is required to be "yyyy/mm/dd hh:mm:ss" (i.e. "1997/06/20 03:25:59).
#$K+MSITRAN.EXE Tool to Generate or Apply a Transform file
The MSITRAN.EXE tool can generate or apply a transform file.  It is a command line tool layered on the MsiDatabaseGenerateTransform, MsiCreateTransformSummaryInfo, and MsiDatabaseApplyTransform Windows Installer API.
Command Line Syntax: 

Transform Generation: msitran -g {base db} {ref db} {transform file name} [{error conditions / validation conditions}] 
Transform Application: msitran -a {transform} {database} [{error conditions}]

Error Conditions:
The following errors may be suppressed when applying a transform. To suppress an error, include the appropriate character in the {error conditions} argument. Conditions specified with -g are placed in the summary information of the transform, but are not used when applying a transform with -a.

'a': Add existing row.
'b': Delete non-existing row.
'c': Add existing table.
'd': Delete non-existing table.
'e': Modify existing row.
'f': Change codepage.

Validation Conditions:
The following validation conditions may be used to indicate when a transform may be applied to a package. These conditions may be specified with -g, but not -a.

'g': Check upgrade code.
'l': Check language.
'p': Check platform.
'r': Check product.
's': Check major version only.
't': Check major and minor versions only.
'u': Check major, minor, and upgrade versions.
'v': Applied database version < Base database version.
'w': Applied database version <= Base database version.
'x': Applied database version = Base database version.
'y': Applied database version >= Base database version.
'z': Applied database version > Base database version.

Generate transform without Summary Information Stream:
The conditions are ignored.
'@': Suppress summary information stream generation.

#$K+ORCA.EXE Tool for package editing and creation
The ORCA.EXE tool can be used for creating and editing MSI packages and merge modules. The tool also provides a graphical interface for validation, highlighting the particular entries where validation errors and/or warnings occur. 
Command Line Syntax: 

orca [<options>] [<source file>]

The following are general command line options supported by ORCA
-q Quiet mode 
-s <database> Schema database ["orca.dat" - default]
-? Help dialog

The following are Merge Module command line options
-c Commit merge to database if no errors.
-m <module> Merge Module to merge into database
-f Feature[:Feature2] Feature(s) to connect to Merge Module
-r <directory id> Directory entry for module root redirection
-x <directory> Extract files to source image under directory
-g <language> Language used to open module
-l <log file> File to use as log, append if already exists
Remarks:
If merging, -f, -m and <sourcefile> are all required.

#$K+MSIVAL2.EXE Command line tool to run ICE validation.
The MSIVAL2.EXE tool can run a suite of ICE validators or an individual ICE.
Command Line Syntax:
msival2 {database} {CUB file} [-f] [-l {logfile}] [-i {ICE Id}[:{ICE Id}...]]

The following case-insensitive command line options are supported (slash delimiter may also be used).
 -F     Filter out informational messages from the displayed results.
 -I     Run only the selected ICE(s). 
 -L     Write results to the specified file. 
Remarks:
If the -I(i) option is used, the tool will run only the listed ICE validators, in the order specified. Each ICE should be specified as it is listed in the CustomAction table of the CUB file. If the -I(i) option is omitted, the tool runs the default set of ICEs defined by the author of the CUB file.
The -F option will not display or log any ICE INFO messages. All other types of messages will be displayed.
The file specified with the -L must not exist. If it does, it will not be overwritten. The -F option will filter messages sent to the log as well. The results will still be visible on the screen.
#$K+MSIMERG.EXE Tool to Merge a database into another
The MSIMERG.EXE tool can merge a database into another.  If MergeConflicts are reported, information is placed in the _MergeErrors table.  Note, the _MergeErrors table may not always be created depending on the error that occured (an error not related to the actual merge of the data).  It utilizes the external API, in particular, MsiDatabaseMerge.  
Command Line Syntax 
msimerg {base db} {ref db}

#$K+MSIZAP.EXE Tool to clean up Windows Installer information if a failure has occurred.
The MSIZAP.EXE tool can clean up Windows Installer information for a product or all products installed on a machine  
Command Line Syntax 
msizap T[A!] {product code} 
msizap T[A!] <msi package> 
msizap *[A!] ALLPRODUCTS 
msizap PSA?! 

Option explanations 
* remove all Windows Installer folders and regkeys; adjust shared DLL counts; stop Windows Installer service 
T remove all info for given product code 
P remove In-Progress key 
S remove Rollback Information 
A for any specified removal, just change ACLs to Admin Full Control 
? verbose help 
! force 'yes' response to any prompt 

Remarks:
When using the T option with the Product Code, include the curly braces around the Product Code.

CAUTION: Products installed by the Windows Installer may fail to function after using MsiZap.
#$K+Makefile for Building Tools and Custom Actions
MSITOOL.MAK is a makefile that can be used to make tools and custom actions, using VC4.x or VC5. See header of that file for documentation. It requires a set of values to be defined before including this file. Typically we put those at the start of the CPP, ifdef'd to be skipped by the C compiler. Likewise resources are added to the end of the CPP file. See samples for details.

VCBIN may be defined to the directory where the VC tools are found, else the makefile uses MSVCDIR and MSDEVDIR, and if those aren't defined, it does not specify a location, assuming the tools to be on the PATH. A problem with the environment variables in VC5 is that if both are NOT on you path, the linker can't find MSDIS100.DLL. If you copy that from MSDEVDIR to MSVCDIR, it works OK. The other thing that you can do is to copy MSDIS100.DLL and RC.EXE and RCDLL.DLL to MSVCDIR, and set VCBIN to that.
#$K+MsiSpy: A Tool to Display Component-Level View of A System

MsiSpy provides a component level view of the products and features installed on a system, using either an MSI Package, or the registry information. Msispy also displays the status of each, and allows you to partially or completely re-install missing or damaged items. You  can also re-configure any product or feature, selecting the install level, and specifying whether to install it locally or run it from a network server.
Please select a topic you would like more information on:
Menu Options
Context Menus
Command Line Options
Setting Preferences
Msispy Automation Interface

 #$K+Menu Options

The File Menu
Open MSI Package allows you to open an MSI package.
Open Local Database uses the registry information to display information about all the products installed on the computer.
Load Saved State allows you to load a profile of the system previously saved by Msispy.
Save Current State allows you to save a complete profile of the system onto a file. The information is stored in an easy to read text format. This information should not be modified directly.
Restore Saved State (enabled only when a saved state is loaded) attempts to restore the system to the configuration in the saved state. If more components have been added since the profile was saved, they are left untouched. If some products or components have been damaged since the profile was saved, Msispy attempts to restore them by attempting to re-install them from the original source. If the source is not available, you are given the option to abort, retry or ignore.
Check Differences (enabled only when a saved state is loaded) checks the differences between the configuration in the saved state and the current system configuration. These differences are written to a log file in a tab-separated table in simple text format.

The View Menu
Refresh refreshes the display by getting the displayed information again and redrawing it.
Prefences allows you to change the Msispy mode and language. For more information, refer to Setting Preferences.

The Help Menu
Overview brings up the Msispy help file
About brings up the product information box, with information about the registered user and the version and product ID of the installed copy of Msispy.

Context Menus
Command Line Options

#$K+Context Menus

When a product, feature or component is selected, clicking on the right mouse-button brings up the  context menus that allow you to perform operations on the selected item.

Properties
All context menus have a Properties option, that brings up a property sheet containing information about the selected item. In addition to the General tab that contains the information, the property sheets also contain a File List tab, that contains information about all the files needed by the selected item. The list of files contains information about the file including the component that uses it, the file name and size when it was installed, the location of the file. In this tab, the Verify Files button allows you to check the current status of the files. This button brings up a window with the current file information, including current size, creation, last access and modification dates. If the file is not found, or if the file size is different, the file is marked broken with an icon to the its left.
Important: If a saved state is in use, the verify files brings up information about the files when the state was saved, not the current file information.

Additional context-menu choices cary depending on the item selected:

Components
The menu comprises:
Re-install Component (enabled only if the component is broken), which allows you to re-install the component from it's original install source.

Installed Products (and their Features)
The menu comprises:
Re-install, which allows you to use one of the available re-install modes, including options to re-install just the damaged or missing files. Other options allow you to force all the files to be re-installed, the registry entries to be verified, and so on.
Configure, which allows you to install the feature on your local machine, or run it from a remote source. Some features may have components that need to be installed on the local machine. Attempting to install such features to run from a remote location will lead to a mix of some components being on the local system and the rest at the remote location.
Un-install, which allows you to un-install the product or feature. If a feature with sub-features is un-installed, all of its sub-features will be un-installed as well. If the last installed feature in a product is un-installed, the entire product will be un-installed.

Other Products (and their Features)
If an MSI package for a product not installed on the local system  is in use, the context menu has the following options:
Install Product, which will install the product on the local system using the default options.
Advertise Product, which will advertise the product on to the local system. This will set all the registry entries needed for the product, but will not actually install any files on the local system. The files will be transferred in when the component they belong to is used.

Products in Saved States (and their Features)
If a saved state is loaded, the menu always comprises:
Restore Saved State, which has the same functionality as Restore Saved State described under  Menu Options.

Menu Options
Command Line Options

#$K+Msispy Command Line Options

msispy [filename|/options filename(s)]

/d<srcprof.msp> <destfile.log>
Saves the differences between the current system configuration and the profile <srcprof.msp> into <destfile.log> in a tab-separated table form.
/s<destprof.msp>
Saves the current system configuration to the profile <destprof.msp>
/r<srcprof.msp>
Restores the current system to the configuration in the profile <srcprof.msp>
<srcprof.msp>
Launches GUI version and loads the profile <srcprof.msp>
without any command-line option
Launches GUI version

Menu Options
Context Menus

#$K+Setting Preferences

Msispy can be used in different modes, and in different languages. You can set your preferences by selecting "Preferences" under the View Menu.
Modes
Msispy can be used in the following modes:
Normal: This is the default Msispy mode. In this mode, Msispy determines the status of a component solely on the basis of the component key-file. This makes Msispy much faster, and in most cases will present an accurate picture of the component status. All the features of Msispy are available in this mode.
Diagnostic: In this mode, Msispy will perform a complete check of all files to determine component status, instead of relying on component key files. This mode will give a more accurate picture of the component status, but will make the program significantly slower. Msispy should not normally be used in this mode, especially if it is being used on a slow machine.
Restricted: In this mode, the functionality of Msispy is limited to the Local Database only. You will not be able to access MSI Packages or Msispy Saved States. Leads to a slight performance gain. This mode is recommended if you are on slow machines and do not wish to take advantage of all the Msispy features.
If Msispy is unable to load the system interface DLL (default name msispyu.dll), it will start up in the restricted mode. You will not be able to switch to any other mode, since the other modes need the system interface DLL to function. To restore Msispy to it's full functionality, you may need to perform a re-install from the original install source.

Languages
Msispy can be used in many languages if the Msispy language support components are installed. A list of all supported languages appears in the "Language" tab of the preferences property sheet. To select a different language, click on the new language, and select OK. Msispy will switch to the new language automatically, if the language resources for the new language can be loaded. If the new language cannot be loaded, Msispy will load the closest match if available. If there is no similar language available, default language will be loaded.

#$KMsispy Automation Interface
Access to C++ Libraries
An Msispy object must be initially created in order to load  the automation support that is required in order to access the Msispy objects through OLE automation. This object provides wrappers to create the top level objects and access their methods. These wrapper simply provide argument translations to expose the Msispy functions in a manner consistent with BASIC without changing the behavior of the methods. When possible, a pair of Get and Set C++ methods will be exposed to BASIC as a single property. Where appropriate, C++ methods taking an index argument will be exposed as an indexed property. Many C++ methods return the result through an argument, as the return value is used for the error return; however in BASIC errors are handled by a separate mechanism, and the result is always passed in the return value.
Creating the Msispy object
In order for OLE to access the automation, the DLL must be registered. This can be done in one of two ways- (a) by installing Msispy on your system using MSI, or (b) self-registering the DLL. The OLE ProgId used to create the Msispy object is Msispy.Automation.
#$KMsispy Automation Objects
Msispy object
MsispyDatabase object
MsispyProfile object
MsispyRegistry object

#$K+Msispy Object
An Msispy object must be initially created in order to load the automation support that is required in order to access the Msispy automation functionsthrough OLE automation. This object provides wrappers to create the top level objects and access their methods.
Methods
CreateDatabase
CreateProfile
CreateRegistry

#$+KCreateDatabase Method
	Msispy Object	Msispy Objects
Returns a new MsispyDatabase object.
Syntax
object.CreateDatabase()
object
Required. The Msispy object.
#$+KCreateProfile Method
	Msispy Object	Msispy Objects
Returns a new MsispyProfile object.
Syntax
object.CreateProfile()
object
Required. The Msispy object.
#$+KCreateRegistry Method
	Msispy Object	Msispy Objects
Returns a new MsispyRegistry object.
Syntax
object.CreateRegistry()
object
Required. The Msispy object.
#$K+MsispyDatabase Object
	Msispy Objects
The database object accesses a Microsoft Installer database.
Before the MsispyDatabase object is released (by going out of scope or by setting the object variable to Nothing), the Close method must be called to release all handles.
Properties
GetProduct
GetFeatureFromProduct
GetProduct
GetFeatureFromProduct
GetComponent
GetComponentFromProduct
GetComponentFromFeature
GetComponentName
GetProductInfo
GetFeatureInfo
QueryProductState
QueryFeatureState
QueryComponentState
GetFeatureUsage
GetClientFromComponent
GetFileFromComponent
GetFileInfo
GetComponentLocation
GetComponentPath

Methods
Open
Close

#$+KOpen Method
	MsispyDatabase Object	Msispy Objects
Opens a database at the location specified.
Syntax
object.Open(databasePath)
object
Required. The MsispyDatabase object.
databasePath
Required. The location of the database.
#$+KClose Method
	MsispyDatabase Object	Msispy Objects
Closes a database, releasing the database handles.
Syntax
object.Close()
object
Required. The MsispyDatabase object.
#$+KGetProduct Property
	MsispyDatabase Object	Msispy Objects
Returns a string containing the product-code of a product in the database, or a blank string if all the products in the database have been enumerated. A 0-based index is used to enumerate the products one at a time.
Syntax
object.GetProduct(productIndex)
object
Required. The MsispyDatabase object.
productIndex
Required. The 0-based index used for enumeration.
#$+KGetFeatureFromProduct Property
	MsispyDatabase Object	Msispy Objects
Returns a string containing the name of a feature of the product, or a blank string  if all the features of the product have been enumerated. A 0-based index is used to enumerate the features one at a time. The product being used must be in the database, otherwise no features are enumerated.
Syntax
object.GetFeatureFromProduct(productCode, featureIndex)
object
Required. The MsispyDatabase object.
productCode
Required. The product whose features are to be enumerated, must be in the database.
featureIndex
Required. The 0-based index used for enumeration.
#$+KGetComponent Property
	MsispyDatabase Object	Msispy Objects
Returns a string containing the GUID of a component in the database, or a blank string if all the components in the database have been enumerated. A 0-based index is used to enumerate the components one at a time.
Syntax
object.GetComponent(componentIndex)
object
Required. The MsispyDatabase object.
componentIndex
Required. The 0-based index used for enumeration.
#$+KGetComponentFromProduct Property
	MsispyDatabase Object	Msispy Objects
Returns a string containing the GUID of a component of the product, or a blank string  if all the components of the product have been enumerated. A 0-based index is used to enumerate the components one at a time. The product being used must be in the database, otherwise no components are enumerated.
Syntax
object.GetComponentFromProduct(productCode, componentIndex)
object
Required. The MsispyDatabase object.
productCode
Required. The product whose components are to be enumerated, must be in the database.
componentIndex
Required. The 0-based index used for enumeration.
#$+KGetComponentFromFeature Property
	MsispyDatabase Object	Msispy Objects
Returns a string containing the GUID of a component of the feature, or a blank string  if all the components of the feature have been enumerated. A 0-based index is used to enumerate the components one at a time. The product in use must be in the database, otherwise no components are enumerated.
Syntax
object.GetComponentFromFeature(productCode, featureName, componentIndex)
object
Required. The MsispyDatabase object.
productCode
Required. The product in use, must be in the database.
featureName
Required. The feature whose components are to be enumerated.
componentIndex
Required. The 0-based index used for enumeration.
#$+KGetComponentName Property
	MsispyDatabase Object	Msispy Objects
Returns a string containing the name of a component whose GUID is passed in, or a blank string if the required information could not be found.
Syntax
object.GetComponentName(componentGuid)
object
Required. The MsispyDatabase object.
componentGuid
Required. The component whose name will be returned.
#$+KGetProductInfo Property
	MsispyDatabase Object	Msispy Objects
Returns a string containing a specific property of a product, or a blank string if the required information could not be found.
Syntax
object.GetProductInfo(productCode, productAttribute)
object
Required. The MsispyDatabase object.
productCode
Required. The product about which information will be returned.
productAttribute
Required. The required property of the product (case-sensitive). Valid attributes are:
	ProductName
	ProductVersion
	ProductCode
	Manufacturer
	SupportURL
	SupportPhone
	UserName
	UserOrgName
	ProductId

#$+KGetFeatureInfo Property
	MsispyDatabase Object	Msispy Objects
Returns a string containing a specific property of a feature, or a blank string if the required information could not be found.
Syntax
object.GetFeatureInfo(productCode, featureName, featureAttribute)
object
Required. The MsispyDatabase object.
productCode
Required. The product to which the feature belongs.
featureName
Required. The feature about which information will be returned.
featureAttribute
Required. The required property of the feature (case-sensitive). Valid attributes are:
	Feature
	Feature_Parent
	Title
	Description
	Display
	Level
	Directory_Configurable
	RunFromSource

#$+KQueryProductState Property
	MsispyDatabase Object	Msispy Objects
Returns a numeric value that represents the install-state of a product on the local system. The value returned is one of the following:
	-6: configuration data corrupt
	-5: installation suspended or in progress
	-4: run from source, source is unavailable
	-3: return buffer overflow
	-2: invalid function argument
	-1: unrecognized product or feature
	 0: broken
	 1: advertised
	 2: uninstalled
	 3: installed on local drive
	 4: run from source, CD or net
	 5: use default, local or source

Syntax
object.QueryProductState(productCode)
object
Required. The MsispyDatabase object.
productCode
Required. The product about which information will be returned.
#$+KQueryFeatureState Property
	MsispyDatabase Object	Msispy Objects
Returns a numeric value that represents the install-state of a feature on the local system. The value returned is one of the following:
	-6: configuration data corrupt
	-5: installation suspended or in progress
	-4: run from source, source is unavailable
	-3: return buffer overflow
	-2: invalid function argument
	-1: unrecognized product or feature
	 0: broken
	 1: advertised
	 2: uninstalled
	 3: installed on local drive
	 4: run from source, CD or net
	 5: use default, local or source

Syntax
object.QueryFeatureState(productCode, featureName)
object
Required. The MsispyDatabase object.
productCode
Required. The product to which the feature belongs.
featureName
Required. The feature about which information will be returned.
#$+KQueryComponentState Property
	MsispyDatabase Object	Msispy Objects
Returns a numeric value that represents the install-state of a component on the local system. The value returned is one of the following:
	-6: configuration data corrupt
	-5: installation suspended or in progress
	-4: run from source, source is unavailable
	-3: return buffer overflow
	-2: invalid function argument
	-1: unrecognized product or feature
	 0: broken
	 1: advertised
	 2: uninstalled
	 3: installed on local drive
	 4: run from source, CD or net
	 5: use default, local or source

Syntax
object.QueryComponentState(productCode, componentGuid)
object
Required. The MsispyDatabase object.
productCode
Required. The product to which the component belongs.
componentGuid
Required. The component about which information will be returned.
#$+KGetFeatureUsage Property
	MsispyDatabase Object	Msispy Objects
Returns the usage-count of a feature on the local system. Returns 0 if the information could not be obtained.
Syntax
object.GetFeatureUsage(productCode, featureName)
object
Required. The MsispyDatabase object.
productCode
Required. The product to which the feature belongs.
featureName
Required. The feature about which information will be returned.
#$+KGetClientFromComponent Property
	MsispyDatabase Object	Msispy Objects
Returns a string containing product-code of a client-product of the component, or a blank  string if all the clients of the component have been enumerated. A 0-based index is used to enumerate the clients one at a time. The component being used must be in the database, otherwise no clients are enumerated.
Syntax
object.GetClientFromComponent(componentGuid, clientIndex)
object
Required. The MsispyDatabase object.
componentGuid
Required. The component whose clients are to be enumerated, must be in the database.
clientIndex
Required. The 0-based index used for enumeration.
#$+KGetFileFromComponent Property
	MsispyDatabase Object	Msispy Objects
Returns a string containing the name of a file used by the component, or a blank  string if all the files of the component have been enumerated. A 0-based index is used to enumerate the files one at a time. The component being used must be in the database, otherwise no files are enumerated.
Syntax
object.GetFileFromComponent(componentGuid, fileIndex)
object
Required. The MsispyDatabase object.
componentGuid
Required. The component whose files are to be enumerated, must be in the database.
fileIndex
Required. The 0-based index used for enumeration.
#$+KGetFileInfo Property
	MsispyDatabase Object	Msispy Objects
Returns a string containing a specific property of a file, or a blank string if the required information could not be found.
Syntax
object.GetFileInfo(productCode, componentGuid, fileName, fileAttribute)
object
Required. The MsispyDatabase object.
productCode
Required. The product to which the component belongs.
componentGuid
Required. The component to which the file belongs.
fileName
Required. The file about which information will be returned.
fileAttribute
Required. The required property of the file (case-sensitive). Valid attributes are:
	FileTitle
	FileSize
	Version
	Language
	Attributes
	Sequence
	FileActualSize
	FileCreated
	FileModified
	FileAccessed
	FileStatus

#$+KGetComponentLocation Property
	MsispyDatabase Object	Msispy Objects
Returns a string containing the full path to the keyfile of a component.
Syntax
object.GetComponentLocation(componentGuid)
object
Required. The MsispyDatabase object.
componentGuid
Required. The component about which information will be returned.
#$+KGetComponentPath Property
	MsispyDatabase Object	Msispy Objects
Returns a string containing the full path to the keyfile of a component.
Syntax
object.GetComponentPath(productCode, componentGuid)
object
Required. The MsispyDatabase object.
productCode
Required. The product to which the component belongs.
componentGuid
Required. The component about which information will be returned.
#$K+MsispyProfile Object
	Msispy Objects
The profile object accesses a Msispy profile.
Before the MsispyProfile object is released (by going out of scope or by setting the object variable to Nothing), the Close method must be called to release all handles.
Properties
GetProduct
GetFeatureFromProduct
GetProduct
GetFeatureFromProduct
GetComponent
GetComponentFromProduct
GetComponentFromFeature
GetComponentName
GetProductInfo
GetFeatureInfo
QueryProductState
QueryFeatureState
QueryComponentState
GetFeatureUsage
GetClientFromComponent
GetFileFromComponent
GetFileInfo
GetComponentLocation
GetComponentPath

Methods
Open
Close

#$+KOpen Method
	MsispyProfile Object	Msispy Objects
Opens a profile at the given location.
Syntax
object.Open(profilePath)
object
Required. The MsispyProfile object.
profilePath
Required. The location of the profile.
#$+KClose Method
	MsispyProfile Object	Msispy Objects
Closes an open profile.
Syntax
object.Close()
object
Required. The MsispyProfile object.
#$+KGetProduct Property
	MsispyProfile Object	Msispy Objects
Returns a string containing the product-code of a product in the profile, or a blank string if all the products in the profile have been enumerated. A 0-based index is used to enumerate the products one at a time.
Syntax
object.GetProduct(productIndex)
object
Required. The MsispyProfile object.
productIndex
Required. The 0-based index used for enumeration.
#$+KGetFeatureFromProduct Property
	MsispyProfile Object	Msispy Objects
Returns a string containing the name of a feature of the product, or a blank string  if all the features of the product have been enumerated. A 0-based index is used to enumerate the features one at a time. The product being used must be in the profile, otherwise no features are enumerated.
Syntax
object.GetFeatureFromProduct(productCode, featureIndex)
object
Required. The MsispyProfile object.
productCode
Required. The product whose features are to be enumerated, must be in the profile.
featureIndex
Required. The 0-based index used for enumeration.
#$+KGetComponent Property
	MsispyProfile Object	Msispy Objects
Returns a string containing the GUID of a component in the profile, or a blank string if all the components in the profile have been enumerated. A 0-based index is used to enumerate the components one at a time.
Syntax
object.GetComponent(componentIndex)
object
Required. The MsispyProfile object.
componentIndex
Required. The 0-based index used for enumeration.
#$+KGetComponentFromProduct Property
	MsispyProfile Object	Msispy Objects
Returns a string containing the GUID of a component of the product, or a blank string  if all the components of the product have been enumerated. A 0-based index is used to enumerate the components one at a time. The product being used must be in the profile, otherwise no components are enumerated.
Syntax
object.GetComponentFromProduct(productCode, componentIndex)
object
Required. The MsispyProfile object.
productCode
Required. The product whose components are to be enumerated, must be in the profile.
componentIndex
Required. The 0-based index used for enumeration.
#$+KGetComponentFromFeature Property
	MsispyProfile Object	Msispy Objects
Returns a string containing the GUID of a component of the feature, or a blank string  if all the components of the feature have been enumerated. A 0-based index is used to enumerate the components one at a time. The product in use must be in the profile, otherwise no components are enumerated.
Syntax
object.GetComponentFromFeature(productCode, featureName, componentIndex)
object
Required. The MsispyProfile object.
productCode
Required. The product in use, must be in the profile.
featureName
Required. The feature whose components are to be enumerated.
componentIndex
Required. The 0-based index used for enumeration.
#$+KGetComponentName Property
	MsispyProfile Object	Msispy Objects
Returns a string containing the name of a component whose GUID is passed in, or a blank string if the required information could not be found.
Syntax
object.GetComponentName(componentGuid)
object
Required. The MsispyProfile object.
componentGuid
Required. The component whose name will be returned.
#$+KGetProductInfo Property
	MsispyProfile Object	Msispy Objects
Returns a string containing a specific property of a product, or a blank string if the required information could not be found.
Syntax
object.GetProductInfo(productCode, productAttribute)
object
Required. The MsispyProfile object.
productCode
Required. The product about which information will be returned.
productAttribute
Required. The required property of the product (case-sensitive). Valid attributes are:
	ProductName
	ProductVersion
	ProductCode
	Manufacturer
	SupportURL
	SupportPhone
	UserName
	UserOrgName
	ProductId

#$+KGetFeatureInfo Property
	MsispyProfile Object	Msispy Objects
Returns a string containing a specific property of a feature, or a blank string if the required information could not be found.
Syntax
object.GetFeatureInfo(productCode, featureName, featureAttribute)
object
Required. The MsispyProfile object.
productCode
Required. The product to which the feature belongs.
featureName
Required. The feature about which information will be returned.
featureAttribute
Required. The required property of the feature (case-sensitive). Valid attributes are:
	Feature
	Feature_Parent
	Title
	Description
	Display
	Level
	Directory_Configurable
	RunFromSource

#$+KQueryProductState Property
	MsispyProfile Object	Msispy Objects
Returns a numeric value that represents the install-state of a product on the local system. The value returned is one of the following:
	-6: configuration data corrupt
	-5: installation suspended or in progress
	-4: run from source, source is unavailable
	-3: return buffer overflow
	-2: invalid function argument
	-1: unrecognized product or feature
	 0: broken
	 1: advertised
	 2: uninstalled
	 3: installed on local drive
	 4: run from source, CD or net
	 5: use default, local or source

Syntax
object.QueryProductState(productCode)
object
Required. The MsispyProfile object.
productCode
Required. The product about which information will be returned.
#$+KQueryFeatureState Property
	MsispyProfile Object	Msispy Objects
Returns a numeric value that represents the install-state of a feature on the local system. The value returned is one of the following:
	-6: configuration data corrupt
	-5: installation suspended or in progress
	-4: run from source, source is unavailable
	-3: return buffer overflow
	-2: invalid function argument
	-1: unrecognized product or feature
	 0: broken
	 1: advertised
	 2: uninstalled
	 3: installed on local drive
	 4: run from source, CD or net
	 5: use default, local or source

Syntax
object.QueryFeatureState(productCode, featureName)
object
Required. The MsispyProfile object.
productCode
Required. The product to which the feature belongs.
featureName
Required. The feature about which information will be returned.
#$+KQueryComponentState Property
	MsispyProfile Object	Msispy Objects
Returns a numeric value that represents the install-state of a component on the local system. The value returned is one of the following:
	-6: configuration data corrupt
	-5: installation suspended or in progress
	-4: run from source, source is unavailable
	-3: return buffer overflow
	-2: invalid function argument
	-1: unrecognized product or feature
	 0: broken
	 1: advertised
	 2: uninstalled
	 3: installed on local drive
	 4: run from source, CD or net
	 5: use default, local or source

Syntax
object.QueryComponentState(productCode, componentGuid)
object
Required. The MsispyProfile object.
componentGuid
Required. The component about which information will be returned.
#$+KGetFeatureUsage Property
	MsispyProfile Object	Msispy Objects
Returns the usage-count of a feature on the local system. Returns 0 if the information could not be obtained.
Syntax
object.GetFeatureUsage(productCode, featureName)
object
Required. The MsispyProfile object.
productCode
Required. The product to which the feature belongs.
featureName
Required. The feature about which information will be returned.
#$+KGetClientFromComponent Property
	MsispyProfile Object	Msispy Objects
Returns a string containing product-code of a client-product of the component, or a blank  string if all the clients of the component have been enumerated. A 0-based index is used to enumerate the clients one at a time. The component being used must be in the profile, otherwise no clients are enumerated.
Syntax
object.GetClientFromComponent(componentGuid, clientIndex)
object
Required. The MsispyProfile object.
componentGuid
Required. The component whose clients are to be enumerated, must be in the profile.
clientIndex
Required. The 0-based index used for enumeration.
#$+KGetFileFromComponent Property
	MsispyProfile Object	Msispy Objects
Returns a string containing the name of a file used by the component, or a blank  string if all the files of the component have been enumerated. A 0-based index is used to enumerate the files one at a time. The component being used must be in the profile, otherwise no files are enumerated.
Syntax
object.GetFileFromComponent(componentGuid, fileIndex)
object
Required. The MsispyProfile object.
componentGuid
Required. The component whose files are to be enumerated, must be in the profile.
fileIndex
Required. The 0-based index used for enumeration.
#$+KGetFileInfo Property
	MsispyProfile Object	Msispy Objects
Returns a string containing a specific property of a file, or a blank string if the required information could not be found.
Syntax
object.GetFileInfo(productCode, componentGuid, fileName, fileAttribute)
object
Required. The MsispyProfile object.
productCode
Required. The product to which the component belongs.
componentGuid
Required. The component to which the file belongs.
fileName
Required. The file about which information will be returned.
fileAttribute
Required. The required property of the file (case-sensitive). Valid attributes are:
	FileTitle
	FileSize
	Version
	Language
	Attributes
	Sequence
	FileActualSize
	FileCreated
	FileModified
	FileAccessed
	FileStatus

#$+KGetComponentLocation Property
	MsispyProfile Object	Msispy Objects
Returns a string containing the full path to the keyfile of a component.
Syntax
object.GetComponentLocation(componentGuid)
object
Required. The MsispyProfile object.
componentGuid
Required. The component about which information will be returned.
#$+KGetComponentPath Property
	MsispyProfile Object	Msispy Objects
Returns a string containing the full path to the keyfile of a component.
Syntax
object.GetComponentPath(productCode, componentGuid)
object
Required. The MsispyDatabase object.
productCode
Required. The product to which the component belongs.
componentGuid
Required. The component about which information will be returned.
#$K+MsispyRegistry Object
	Msispy Objects
The registry object accesses the local registry on a machine to obtain information about products installed by MSI.
Before the MsispyRegistry object is released (by going out of scope or by setting the object variable to Nothing), the Close method must be called to release all handles.
Properties
GetProduct
GetFeatureFromProduct
GetProduct
GetFeatureFromProduct
GetComponent
GetComponentFromProduct
GetComponentFromFeature
GetComponentName
GetProductInfo
GetFeatureInfo
QueryProductState
QueryFeatureState
QueryComponentState
GetFeatureUsage
GetClientFromComponent
GetFileFromComponent
GetFileInfo
GetComponentLocation
GetComponentPath

Methods
Open
Close

#$+KOpen Method
	MsispyRegistry Object	Msispy Objects
Opens a registry object.
Syntax
object.Open()
object
Required. The MsispyRegistry object.
#$+KClose Method
	MsispyRegistry Object	Msispy Objects
Closes a registry object.
Syntax
object.Close()
object
Required. The MsispyRegistry object.
#$+KGetProduct Property
	MsispyRegistry Object	Msispy Objects
Returns a string containing the product-code of a product in the registry, or a blank string if all the products in the registry have been enumerated. A 0-based index is used to enumerate the products one at a time.
Syntax
object.GetProduct(productIndex)
object
Required. The MsispyRegistry object.
productIndex
Required. The 0-based index used for enumeration.
#$+KGetFeatureFromProduct Property
	MsispyRegistry Object	Msispy Objects
Returns a string containing the name of a feature of the product, or a blank string  if all the features of the product have been enumerated. A 0-based index is used to enumerate the features one at a time. The product being used must be in the registry, otherwise no features are enumerated.
Syntax
object.GetFeatureFromProduct(productCode, featureIndex)
object
Required. The MsispyRegistry object.
productCode
Required. The product whose features are to be enumerated, must be in the registry.
featureIndex
Required. The 0-based index used for enumeration.
#$+KGetComponent Property
	MsispyRegistry Object	Msispy Objects
Returns a string containing the GUID of a component in the registry, or a blank string if all the components in the registry have been enumerated. A 0-based index is used to enumerate the components one at a time.
Syntax
object.GetComponent(componentIndex)
object
Required. The MsispyRegistry object.
componentIndex
Required. The 0-based index used for enumeration.
#$+KGetComponentFromProduct Property
	MsispyRegistry Object	Msispy Objects
Returns a string containing the GUID of a component of the product, or a blank string  if all the components of the product have been enumerated. A 0-based index is used to enumerate the components one at a time. The product being used must be in the registry, otherwise no components are enumerated.
Syntax
object.GetComponentFromProduct(productCode, componentIndex)
object
Required. The MsispyRegistry object.
productCode
Required. The product whose components are to be enumerated, must be in the registry.
componentIndex
Required. The 0-based index used for enumeration.
#$+KGetComponentFromFeature Property
	MsispyRegistry Object	Msispy Objects
Returns a string containing the GUID of a component of the feature, or a blank string  if all the components of the feature have been enumerated. A 0-based index is used to enumerate the components one at a time. The product in use must be in the registry, otherwise no components are enumerated.
Syntax
object.GetComponentFromFeature(productCode, featureName, componentIndex)
object
Required. The MsispyRegistry object.
productCode
Required. The product in use, must be in the registry.
featureName
Required. The feature whose components are to be enumerated.
componentIndex
Required. The 0-based index used for enumeration.
#$+KGetComponentName Property
	MsispyRegistry Object	Msispy Objects
Returns a string containing the name of a component whose GUID is passed in, or a blank string if the required information could not be found.
Syntax
object.GetComponentName(componentGuid)
object
Required. The MsispyRegistry object.
componentGuid
Required. The component whose name will be returned.
#$+KGetProductInfo Property
	MsispyRegistry Object	Msispy Objects
Returns a string containing a specific property of a product, or a blank string if the required information could not be found.
Syntax
object.GetProductInfo(productCode, productAttribute)
object
Required. The MsispyRegistry object.
productCode
Required. The product about which information will be returned.
productAttribute
Required. The required property of the product (case-sensitive). Valid attributes are:
	ProductName
	ProductVersion
	ProductCode
	Manufacturer
	SupportURL
	SupportPhone
	UserName
	UserOrgName
	ProductId

#$+KGetFeatureInfo Property
	MsispyRegistry Object	Msispy Objects
Returns a string containing a specific property of a feature, or a blank string if the required information could not be found.
Syntax
object.GetFeatureInfo(productCode, featureName, featureAttribute)
object
Required. The MsispyRegistry object.
productCode
Required. The product to which the feature belongs.
featureName
Required. The feature about which information will be returned.
featureAttribute
Required. The required property of the feature (case-sensitive). Valid attributes are:
	Feature
	Feature_Parent
	Title
	Description
	Display
	Level
	Directory_Configurable
	RunFromSource

#$+KQueryProductState Property
	MsispyRegistry Object	Msispy Objects
Returns a numeric value that represents the install-state of a product on the local system. The value returned is one of the following:
	-6: configuration data corrupt
	-5: installation suspended or in progress
	-4: run from source, source is unavailable
	-3: return buffer overflow
	-2: invalid function argument
	-1: unrecognized product or feature
	 0: broken
	 1: advertised
	 2: uninstalled
	 3: installed on local drive
	 4: run from source, CD or net
	 5: use default, local or source

Syntax
object.QueryProductState(productCode)
object
Required. The MsispyRegistry object.
productCode
Required. The product about which information will be returned.
#$+KQueryFeatureState Property
	MsispyRegistry Object	Msispy Objects
Returns a numeric value that represents the install-state of a feature on the local system. The value returned is one of the following:
	-6: configuration data corrupt
	-5: installation suspended or in progress
	-4: run from source, source is unavailable
	-3: return buffer overflow
	-2: invalid function argument
	-1: unrecognized product or feature
	 0: broken
	 1: advertised
	 2: uninstalled
	 3: installed on local drive
	 4: run from source, CD or net
	 5: use default, local or source

Syntax
object.QueryFeatureState(productCode, featureName)
object
Required. The MsispyRegistry object.
productCode
Required. The product to which the feature belongs.
featureName
Required. The feature about which information will be returned.
#$+KQueryComponentState Property
	MsispyRegistry Object	Msispy Objects
Returns a numeric value that represents the install-state of a component on the local system. The value returned is one of the following:
	-6: configuration data corrupt
	-5: installation suspended or in progress
	-4: run from source, source is unavailable
	-3: return buffer overflow
	-2: invalid function argument
	-1: unrecognized product or feature
	 0: broken
	 1: advertised
	 2: uninstalled
	 3: installed on local drive
	 4: run from source, CD or net
	 5: use default, local or source

Syntax
object.QueryComponentState(productCode, componentGuid)
object
Required. The MsispyRegistry object.
productCode
Required. The product to which the component belongs.
componentGuid
Required. The component about which information will be returned.
#$+KGetFeatureUsage Property
	MsispyRegistry Object	Msispy Objects
Returns the usage-count of a feature on the local system. Returns 0 if the information could not be obtained.
Syntax
object.GetFeatureUsage(productCode, featureName)
object
Required. The MsispyRegistry object.
productCode
Required. The product to which the feature belongs.
featureName
Required. The feature about which information will be returned.
#$+KGetClientFromComponent Property
	MsispyRegistry Object	Msispy Objects
Returns a string containing product-code of a client-product of the component, or a blank  string if all the clients of the component have been enumerated. A 0-based index is used to enumerate the clients one at a time. The component being used must be in the registry, otherwise no clients are enumerated.
Syntax
object.GetClientFromComponent(componentGuid, clientIndex)
object
Required. The MsispyRegistry object.
componentGuid
Required. The component whose clients are to be enumerated, must be in the registry.
clientIndex
Required. The 0-based index used for enumeration.
#$+KGetFileFromComponent Property
	MsispyRegistry Object	Msispy Objects
Returns a string containing the name of a file used by the component, or a blank  string if all the files of the component have been enumerated. A 0-based index is used to enumerate the files one at a time. The component being used must be in the registry, otherwise no files are enumerated.
Syntax
object.GetFileFromComponent(componentGuid, fileIndex)
object
Required. The MsispyRegistry object.
componentGuid
Required. The component whose files are to be enumerated, must be in the registry.
fileIndex
Required. The 0-based index used for enumeration.
#$+KGetFileInfo Property
	MsispyRegistry Object	Msispy Objects
Returns a string containing a specific property of a file, or a blank string if the required information could not be found.
Syntax
object.GetFileInfo(productCode, componentGuid, fileName, fileAttribute)
object
Required. The MsispyRegistry object.
productCode
Required. The product to which the component belongs.
componentGuid
Required. The component to which the file belongs.
fileName
Required. The file about which information will be returned.
fileAttribute
Required. The required property of the file (case-sensitive). Valid attributes are:
	FileTitle
	FileSize
	Version
	Language
	Attributes
	Sequence
	FileActualSize
	FileCreated
	FileModified
	FileAccessed
	FileStatus

#$+KGetComponentLocation Property
	MsispyRegistry Object	Msispy Objects
Returns a string containing the full path to the keyfile of a component.
Syntax
object.GetComponentLocation(componentGuid)
object
Required. The MsispyRegistry object.
componentGuid
Required. The component about which information will be returned.
#$+KGetComponentPath Property
	MsispyRegistry Object	Msispy Objects
Returns a string containing the full path to the keyfile of a component.
Syntax
object.GetComponentPath(productCode, componentGuid)
object
Required. The MsispyDatabase object.
productCode
Required. The product to which the component belongs.
componentGuid
Required. The component about which information will be returned.