Contents
- Package definition
- Package structure
- Package internal information
- Merge Module
- Files
- Registries
- INI Files
- Shortcuts
- Fonts
- Services
- ODBC (Open DataBase Connectivity)
- System variables
- Properties
- Running custom code from the package
- Custom Actions
- System Search
- Upgrades
- Patching
- Upgrading
- De-hardcoding and Variabilization
- De-hardcoding
- Variabilization
- Vendor MSI
- Definition
- Seller Vendor Customization
- Direct vendor MSI
- Vendor MSI hidden in setup
- Vendor MSI with patch
- Modify an MSI vendor, from cab outside to cab inside, etc.
- Msiexec.exe commands
- Installing a package
- Repairing a package
- Uninstalling a package
- Administrative Installation
- Creating logs
- Applying a patch over a MSI
- Installation with MST
- Active-Setup Mechanism
Package internal information
Merge Module
Merge Modules provide a standard method through which software developers deliver components shared by Windows Installer. They are used to deliver shared resources: files, registries, etc to the applications in the form of a composed file.
A Merge Module is similar in structure to a simplified MSI. But, a Merge Module can not be installed by itself -- it must be integrated inside a package. There are free and paid solutions available for packagers that wish to use Merge Modules databases. You can create new Merge Modules using one of the multiple tools that have Windows Installer as a base (e.g. ORCA).
Advanced Installer allows you to easily create merge modules. Merge modules are the standard way for distributing Windows Installer components and setup logic. Learn how to achieve this with Advanced Installer here.
When integrating a Merge Module inside an .msi package, all of the information and necessary resources for installing the components delivered in the Merge Module get incorporated into the .msi file.
A Merge Module is needed only for installing components, and it is not accessible to the user. Because all of the information needed for the installation of the components is delivered inside a single file, the Merge Module can eliminate conflicts caused by older versions, lack of certain registries, and incorrectly installed files.
The Merge Module is indicated by the .msm extension. It can not be installed on its own because it lacks some vital tables that are usually present inside a .msi.
Here are the specific tables for Merge Module:
Taking it as a self-standing whole, a Merge Module should not be modified under any circumstances. All of the information they contain can be found inside the .msi.
Advanced Installer provides a powerful GUI to make it easy to create and manage Merge Modules. Check it out.
Files
This is one of the few items that Windows Installer can not recreate or reproduce. Files can be stocked individually, near msi, and also compressed into a “cabinet” file (internal or external).
Advanced Installer offers a quick and easy way to manage your application files and shortcuts in the Files and Folders page.
Files use these specific tables: File Table and Removefile Table.
File Table
Let’s go through every column in the File Table:
- File - a unique identifying key of the file inside the msi database;
- Component - an external key from the first column of the Component table - this field identifies the component that controls the file;
- FileName - the name of the file
- File Size - the size of the file in bytes
- Version - the version of the file
- Language - the list of id for the language of the file, separated by commas
- Attributes - bit flags with specifications for the file
- Values
- Read-Only file
- Hidden file
- System file
Sequence - the order of the cabinet files and the files inside the media
Note: Files can be versioned or unversioned.
During the installation, the Installer must determine if a file should or shouldn’t be installed based on the flag of the component where it is located.
Things get complicated when there is an existing file with the same name and placement on the machine (as the one installed from the MSI).
In these situations, the Installer verifies the file’s Version, the creation Date, and the Language. The Installer uses the following rules to determine the installation of said file:
- The higher version wins - the file with the highest version will always overwrite the existing file on the machine.
- File with a version - a file with a version will always be installed over an unversioned file.
- Product’s language favorization - if the installed file has a different language than the file already located in the machine, the file matching the language of the installed product will be prioritized.
- Keeping the multi-language file - it will keep the file that bears multiple languages regardless if it is the file being installed or the one already present on the machine.
Removefile Table
This table contains the lists of the files that will be erased.
You have the choice to erase files during installation, repair, or uninstallation of packages.
If there is no file specified, the empty directory will be erased.
Going through the RemoveFile columns:
- FileKey - the primary key for identifying entrances inside the database.
- Component - the external key in the first column from the Component table; this field refers to the component that controls the file that will be erased next.
- FileName - this column contains the name of the file that will be erased; if the column is empty, then the specified directory will be erased with the condition for it to be empty.
- Dir Property - the name of the property of the path directory where the file that will be erased is located. This property can be the name of a directory from the Directory table, the value of a property set up by a system search, or any other property that refers to a directory.
- IntallMode must be one of the following values:
- it erases only when the associated component is installed
- it erases only when the associated component is uninstalled
- it erases any of the above-mentioned cases
Remarks: Inside the FileName column, you can use names of the files with characters like *(any character) or? (unknown character).
Example - *.tmp - all the files with the tmp extension.
Registries
Registries are a database that keeps different settings of the operating system.
They contain information and settings for all hardware devices, software products from the system, users, etc. When a user modifies certain settings from the Control Panel, extensions, system policies, or from other installed applications, those modifications are found inside registries.
The structure of the registries
Registries are divided into a number of logical sections or “keys”. They will have the name by which they were accessed with Windows API -- it starts with “HKEY”(Abbreviation from “Handle to Key”); often they are abbreviated with a name formed of 3-4 letters which starts with “HK”. The Windows operating system contains two hives: HKEY_LOCAL_MACHINE and HKEY_USERS, just for easy access to the information the Registry Editor shows 5 hives:
- HKEY_CLASSES_ROOT
- HKEY_CURRENT_USER
- HKEY_LOCAL_MACHINE
- HKEY_USERS
- HKEY_CURRENT_CONFIG
Each of those “keys” is divided into “subkeys”, which can contain other subkeys. Also, any key can contain entrances with different values.
The values of those entrances can be as following:
- String
- Binary
- DWORD (a number between 0 and 4.294.967.295[232-1])
- Multi-String
- Expandable
Registry keys are specified with a syntax similar to Windows paths, using backslashes to indicate the hierarchical level.
For example, HKEY_LOCAL_MACHINE\Software\Microsoft\Windows refers to the “Windows” subkey of the “Microsoft” subkey of the “Software” subkey of the HKEY_LOCAL_MACHINE key.
Values are not referenced by this syntax. Value names can contain “\”, leading to ambiguities when referenced using the above syntax.
The HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER nodes have a similar structure, the applications look for their settings in the keys HKEY_CURRENT_USER\Software\Vendor’s name\Version\Settings name and if the settings are not found, they then search in the same location but using HKEY_LOCAL_MACHINE.
When writing the settings, the procedure is reversed - the settings are first written in HKEY_LOCAL_MACHINE, but if they do not have rights to write here, then the setting gets stored in HKEY_CURRENT_USER.
HKEY_CLASSES_ROOT
Abbreviated HKCR, HKEY_CLASSES_ROOT stores information about registered applications, including file associations (extensions), and registries that help record the files used by applications.
Starting with Windows 2000, HKCR is a compilation of HKCU\Software\Classes and HKLM\Software\Classes.
If a certain value is in both subkeys, then the one in HKCU\Software\Classes is used.
Any change in HKEY_CLASSES_ROOT actually occurs in the corresponding CLASSES subkeys (either HKCU or HKLM). The same rule applies the other way around.
If a certain value is in both subkeys, then the one in HKCU\Software\Classes is used.
Any change in HKEY_CLASSES_ROOT actually occurs in the corresponding CLASSES subkeys (either HKCU or HKLM). The same rule applies the other way around.
HKEY_CLASSES_ROOT contains two types of data:
1. Keys and values that associate extensions with various programs (extension - a series of keys that begin with a period, except for the first key with *. These keys can contain any number of characters.)
2. The configuration data of COMs, Visual Basic programs, etc.
This configuration data uses:
- Program Identifiers (ProgID) - subkeys in HKEY_CLASSES_ROOT that define actions that can be performed by various programs on a file: bat file, doc file, inifile. Some identifiers associate programs with COMs.
- Other classes of information that uniquely identify a COM, such as an ActiveX control (CLSID, Interface, TypeLib, AppId, etc.). Ex: HKCR\ CLSID contains all class identifiers. Each identifier is a unique number of 16 bytes.
HKEY_CURRENT_USER
Abbreviated HKCU, HKEY_CURRENT_USER stores settings that are specific to the user currently logged in to the machine. HKCU is a mirror of the current user’s registry in HKEY_USERS.
HKEY_LOCAL_MACHINE
Abbreviated HKLM, HKEY_LOCAL_MACHINE stores settings that apply to all users on that machine. This key is found in the %SystemRoot%\System32\Config\system file on the NT-based version of Windows. Hardware information is located under the SYSTEM key.
HKEY_USERS
Abbreviated HKU, HKEY_USERS stores the corresponding HKEY_CURRENT_USER subkeys for each user registered on the machine.
Under HKEY_USERS, you can see which settings are applied for all users on the machine, while HKEY_CURRENT_USER only shows a small portion of the HKEY_USERS hive -- the portion for the current logged in user.
HKEY_CURRENT_CONFIG
Abbreviated HKCC, HKEY_CURRENT_CONFIG stores information during run; the information in this section is not permanently stored on the hard disk, but regenerated when the system starts.
Editing registry
Manual editing
You can manually edit the Registry using the regedit.exe or regedt32.exe programs. Note that negligent editing of registries often leads to irreversible errors, so it is recommended to always have a backup of them.
Command-line editing
You can manipulate the Registry from the command line using the reg.exe utility-- which is included within Windows and can be downloaded separately.
A reg file (a standard file for storing the registry that can be edited) can be imported from the command line, using the syntax “Regedit /s file”, where /s leads to the addition without asking the user for input (silent).
If the /s parameter is omitted, then the user will need to confirm the operation.
When using the /s regedit parameter, it does not return an error code if the operation fails as reg.exe does.
Registry permissions can also be manipulated through the command line using the subinacle.exe utility.
For example:
subinacl.exe /keyreg HKEY_LOCAL_MACHINE\software /grant = Administrator
Gives full access to the administrator account on these keys.
Script editing
Some languages, such as VBScript, provide functions for editing/manipulating the registry.
To add a registry key with VBScript, you must use the RegWrite function:
Set WshShell = WScript.CreateObject(“WScript.Shell”)
WshShell.RegWrite “HKCU\KeyName\”,””, “REG_SZ”
To delete a registry key with VBScript, you must use the RegDelete function:
Set objShell = Wscript.CreateObject(“Wscript.Shell”)
objhell.RegDelete “HKCU\Control Panel\Desktop\MyValue”
To read a registry key with VBScript, you must use the RegRead function:
strLogonServer = “HKEY_CURRENT_USER\Volatile Environment\LOGONSERVER”
strDNSdomain = “HKEY_CURRENT_USER\Volatile Environment\USERDNSDOMAIN”
Set objShell = WScript.CreateObject(“WScript.Shell”)
WScript.Echo “Logon server: “ objShell.RegRead(strLogonServer)
WScript.Echo “DNS domain: “ objShell.RegRead(strDNSdomain)
Location of registries
The Registry is stored in several files. Depending on the version of Windows you’re using, there are different files and different locations on the machine.
In Windows, the following files that store registry can be found in %SystemRoot%\System32\Config:
- Sam - HKEY_LOCAL_MACHINE\SAM
- Security - HKEY_LOCAL_MACHINE\SECURITY
- Software - HKEY_LOCAL_MACHINE\SOFTWARE
- System - HKEY_LOCAL_MACHINE\SYSTEM
- Default - HKEY_USERS\Default
- Userdiff
The following files are found in the specific directory of each user:
%UserProfile%\Ntuser.dat - HKEY_USERS\<User SID>
%UserProfile%\Local Settings\Application Data\Microsoft\Windows\Usrclass.dat - HKEY_USERS\<User SID> _Classes
Registry specific tables
In MSI, you have two series of tables for Registry:
- specific tables that register COMs and extensions (AppId, Class, Extension, MIME, ProgId, TypeLib, Verb) and
- tables that add Services, drivers or ODBCs (ODBCAttribute, ODBCDriver, ODBCDataSource, ODBCSourceAtribute, ODBCTranslator, ServiceInstall).
The Registry table contains the rest of the registry that cannot be included in the tables mentioned above.
When populating registry tables, it is important to try to minimize the number of registries placed in the Registry table and maximize the use of advertised tables.
Windows Installer does not distinguish between the various keys in the registry table and cannot use the internal logic needed to take advantage of some Windows Installer advantages (such as “advertising” for example).
The tables containing the registry are interconnected and dependent on each other as seen on the diagram below. The figure also shows the Component, Feature, File and Icon tables. They are not part of the group of tables that contain the registry, but are entered in the schema to highlight the logic of the schema
Later in this book, we will discuss the second series of tables.
Extension
The Extension table contains information about file name extension servers that must be generated as a part of product advertisement.
Columns:
Extension
- the extension associated with this entry
- must not exceed 255 characters
- the dot does not appear in the name of the extension
ProgId
- program ID associated with this extension
- external keys in the ProgId table
Feature
- foreign key in the Feature table
Component
- foreign key in the Component table
- this column controls the installation of the extension
MIME
- foreign key in the MIME table
- the content type associated with this extension
ProgId
This table associates program identifiers with class identifiers.
ProgID columns:
ProgId - program id or version-independent program id.
The progId will be written to the registry only if that progid has an associated CLSID (Class table, ProgId_Default column) or if the progid has an associated extension (Extension table, ProgId_ column), and that extension has an associated verb (Verb table).
ProgId_Parent
- defined only for independent version program ids
- is a foreign key in the ProgId column.
ProgId_Parent is defined for the version-independent program IDs. This field is the foreign key in the ProgId column. To define an independent program ID, the ProgId_Parent field must be filled into the corresponding ProgId.
Version Independent Program IDs are written to the registry only when they function in association with a CLSID. The ProgId’s child no longer needs to be associated with its CLSID (Class_ column in the ProgId table), only the parent needs to be associated with the CLSID.
Observation: The ProgId table only knows how to register one child of a ProgId. If a ProgId has more than one child and you try to register all of them in the table, you will see that the table records only one child. If you have this situation, register only one child in the table, and associate the other children with CLSID in the table and the HKCR registry\product_name\CurVer write it from the Registry table.
Class
- a foreign key in the Class table
- this column must be null for an independent program id version
The Class_ column is the foreign key in the Class table. This column must be Null for a version independent program ID (ProgId son).
If this field is Null, the program ID will be registered via the Extension table (ProgId_ column), if that extension has an associated verb (Verb table). ProgIds registered in this way do not know how to register ProgId son
Description - a short description associated with this program id
Icon
- foreign key in table Icon
- specify the icon associated with this program id
- this column must be empty for an independent program id version
IconIndex
- the icon index
- this column must be null for an independent program id version
Verb
This table associates various actions with the extensions in the Extension table.
Verb columns:
The Extension_ column represents the extension associated with that verb. This field is the foreign key in the Extension table.
The Verb column represents the verb associated with the respective extension. The following equivalent registry is written:
HKEY_CLASSES_ROOT\ProgId_name\shell\verb_name
The Command column represents the text displayed by the context menu of the extension (right click on the extension: e.g. Open, Edit, Print).
Argument column - in this field you can define a property in the MSI -- the value of the property will be written in the registry.
The following equivalent registry is written in:
HKEY_CLASSES_ROOT\ProgId_name\shell\verb_name
This registry has the value: the keypath file on the component to which the argument value extension belongs to.
For example, if the default registry has the value:
“C:\Program Files\ABC\abc.exe” “%1” “C:\Program Files\ABC\abc.exe”
Then “C:\Program Files\ABC\abc.exe” is the path to the keypath file on the component that belongs to the extension, and “%1” “C:\Program Files\ABC\abc.exe” is the argument.
Observation: If you write [!Filename] in the registry (in the Argument column), it will write a long path. It seems that the installer does not know how to read the shortcut in this column, although its type is Formatted.
The Sequence column represents the sequence of commands associated with an extension. The verb with the smallest sequence becomes the default verb of that extension.
It appears in the registry as follows:
HKEY_CLASSES_ROOT\program_name\shell
Note: This table is referenced by the standard RegisterExtens and UnregisterExtensionInfo actions.
TypeLib
This table provides information for registering type libraries.
LibID | Language | Component | Version | Description | Directory | Feature | Cost |
TypeLib columns:
The LibID GUID column identifies the TypeLib. In the registry it is written at the location:
HKEY_CLASSES_ROOT\typelib\{Identificator_TypeLib}
The Language column represents the language of Typelib. It must be a non-negative number (e.g. 0, 1).
The Version column represents the typelib version. “Minor version” and “Major version” are 4-byte encodings. “Minor version” is represented by the last 8 bits. “Major version” is represented by the 16 bits located in the middle.
Example:
If the version of a Typelib is 1.2 in the table we will write the value 258 for the following reasons:
- 2 in binary (base 2) is 10
- 1 in binary is 1
So in 4-byte transcription it would be: 00000000 00000000 00000001 00000010. If you turn this number into base 10, it will result in 258, the value to be written in the table (in the Version column).
In the registry, it will be written as follows:
HKEY_CLASSES_ROOT\typelib\{Identificator_TypeLib}\Typelib_Version
The Directory_ column is the foreign key in the first column of the Directory table. In the registry, it will be written as follows:
HKEY_CLASSES_ROOT\typelib\{Identificator_TypeLib}\ Typelib_Version\HELPDIR
The Feature_ column is the foreign key in the first column of the Feature table. This column specifies the Feature that must be installed for a TypeLib to be operational.
The Component_ column is the foreign key in the first column of the Component table. This column identifies the component whose keypath is the typelib to be registered. In the registry, it is written to the key <default> from the location:
HKEY_CLASSES_ROOT\typelib\{Identificator_TypeLib}\Typelib_version\0\Win32
The <default> registry in the above location has the value: path to the file that is the keypath of the component.
The Description column represents the description of the Typelib. In the registry, it is written in the key <default> from the location:
HKEY_CLASSES_ROOT\typelib\{Identificator_TypeLib}\Typelib_version
The Cost column represents the cost associated with registering a Typelib in bytes. This field must be a positive or null number.
Remarks:
- This table is referenced by the standard actions RegisterTypeLibraries and UnregisterTypeLibraries. The standard RegisterTypeLibraries custom action needs the typelib language (Language column in the TypeLib table) to be defined correctly, otherwise, the installer will fail to register the Typelib.
- It is possible to register a Typelib without mentioning its version in the table. If you have a TypeLib with version c.0 (letter.0), you can register it from the table. You can leave the Version column Null. The installer ignores what is completed in this column. No matter what you write in this column, the registry is populated with what you need (i.e. the actual version of Typelib).
- If you fill in a description that is different from the one in the ActiveX file in the Typelib table (in the Description column), the registry will be populated with the description from the ActiveX file -- so practically the Description column is ignored.
- If we do not specify the directory that Typelib belongs to in the Directory_ column, then the HELPDIR key will have no value. So, this column must be filled. The installer will not ignore this column.
MIME
This table associates a “MIME context type” with a CLSID or extension.
The ContentType column represents the MIME content identifier. It normally appears as a type/format.
The Extension_ column is the foreign key in the Extension table and associates a MIME with an extension.
The CLSID column can be a foreign key in the CLSID table or it can be a CLSID that already exists on the machine.
In the registry it is written at:
HKCR\MIME\Database\Content Type\[MIME_Name]
HKCR\MIME\Database\Content Type\[MIME_Name]\Extension
If MIME is associated with a CLSID, the CLSID will be created at the HKCR\MIME\Database\Content Type\[MIME_Name] location.
Remarks:
- A MIME must have an associated extension (Extension_ column) to be written to the registry.
- This table is referenced by the standard registerMIMEInfo and UnregisterMIMEInfo custom actions.
SelfReg
This table provides information for self-registering files.
File_ - External key into the first column of the File table indicating the module that needs to be registered.
Cost - The cost of registering the module in bytes. This must be a non-negative number.
Class
This table provides information for registering class identifiers or COM objects
CLSID | Context | Component | Description | AppID | FileTypeMask | Icon | IconIndex | DefInprocHandler | Argument | Feature | Attributes |
A class will not be registered on the machine if one of the CLSID, Context, Component_ and Feature_ fields is not present.
The CLSID column in the table will write the following registry key on the machine:
HKCR\CLSID\<GUID>
The ProgId_Default column represents the Program ID associated with the CLSID. This column is the foreign key in the ProgID table.
The key will be created in the registry:
HKCR\CLSID\<GUID>\ProgID
A <default> key with the name of the ProgID in the ProgID table will be written in the ProgID key.
The Description column represents the description associated with the CLSID. In the registry, the associated key is the following:
HKCR\CLSID\<GUID>\<default>
The <default> key has the value in the Description column.
Note: The son of ProgID in the ProgID table will be written in the registry under the following key:
HKCR\CLSID\<GUID>\VersionIndependentProgID\<default>
The Context column will write one of the following keys, depending on the context:
HKCR\CLSID\<GUID>\LocalServer (16-bit)
HKCR\CLSID\<GUID>\LocalServer32 (32-bit)
HKCR\CLSID\<GUID>\InprocServer (16-bit)
HKCR\CLSID\<GUID>\ InprocServer32 (32-bit)
The AppId_ column contains a foreign key from the AppId table. It appears in the registry as follows:
HKCR\CLSID\<GUID>\APPID
The AppID registry key has the following value: The AppId GUID in the AppId table.
The FileTypeMask column appears in the registry in the following key:
HKCR\FileType\<GUID>
If there are several patterns, they must be delimited by a semicolon (;) , and numeric subkeys will be generated dynamically: 0,1,2, etc.
The Icon_ column represents the icon associated with the CLSID ( which represents a foreign key in the Icon table, where the icons are registered binary as streams). It appears in the registry as follows:
HKCR\CLSID\<GUID>\DefaultIcon
The <default> key in the path above will have the following value:
C:\WINDOWS\Installer\[ProductCode]\icon_name_from_Icon_Table, IconIndex
The IconIndex column represents the icon index. It can be NULL, and there must only be positive numbers.
The Feature column represents the Feature to which the CLSID belongs (foreign key in the Feature table).
The Component_ column specifies the component to which the respective class belongs to. The keypath on this component represents the file in which that class will type.
DefInprocHandler column - this field must be Null if in the Context field we have InprocServer or InprocServer32 (if it is not Null, we will have validation errors). This field can have the following values:
Value | Description |
Non-numeric value | The installer treats a non-numeric value from the DefInprocHandler field as a system file that serves as the “process handler” specified by the registry key: HKCR\CLSID\<GUID>\InprocHandler32 |
Null | The Argument and DefInprocHandler fields can be Null for LocalServer and LocalServer32 contexts. |
1 | The default 16-bit process handler (ole2.dll); In the registry, the default key in HKCR\CLSID\<GUID>\InprocHandler will have the value ole2.dll. |
2 | The default 32-bit process handler (ole32.dll); The default registry key in HKCR\CLSID\<GUID>\InprocHandler32 will have the value ole32.dll. |
3 | It will create both the 16-bit and the 32-bit process handler; The registry keys are: HKCR\CLSID\<GUID>\InprocHandler and HKCR\CLSID\<GUID>\InprocHandler32 |
Argument column - an argument appears at a CLSID only if the context of that class is LocalServer or LocalServer32 (otherwise validation errors will occur). In this field, you can add a defined property in the MSI which will write in the following registry key:
HKCR\CLSID\<GUID>\LocalServer
or
HKCR\CLSID\<GUID>\LocalServer32
Remarks:
- If in the context of a class we have LocalServer or LocalServer32, then the value of the default registry in HKCR\CLSID\<GUID>\LocalServer or HKCR\CLSID\<GUID>\LocalServer32 will be the shortcut to the file that is a keypath on the component (in which case, the attribute of the respective class is set to 0)
- If in the context of a class, we have InprocServer or InprocServer32, then the default registry value in HKCR\CLSID\<GUID>\InprocServer or HKCR\CLSID\<GUID>\InprocServer32 will be a long path to the file that is a keypath on the component.
- If you write [!Filename] in the Arguments column, then a long path will be written in the registry.
Attributes column - if this field is set to 0 or Null, then the registry will be written with the keypath to the file. If the field is set to 1, then only the name of the file will be written in the registry.
AppId
To register an AppID in the registry, it is enough for a single field to be filled in, namely the AppId field (it is the only field in this table that cannot be Null). However, the AppID must be associated with a CLSID (the AppId column in the Class table must be completed).
The AppID table is used to register various configurations for DCOMs
AppID | RemoteServerName | LocalService | ServiceParameters | DllSurrogate | ActivateAtStorage | RunAsInteractiveUser |
AppId column - appears in the registry: HKCR\AppID\<GUID_AppID>\ and in the key GUID_AppID in HKCR\CLSID\<GUID_CLSID>\ (The AppId is associated with the CLSID in the Class table, the AppId column).
Observation: In order for an AppId to be registered in the HKCR\AppID\<GUID_AppID>\ registry key, that AppId must be associated with a CLSID in the Class table (AppId column).
RemoteServerName column - in this field you can add the value of a property. The RemoteServerName key is written to HKCR\AppID\<GUID_AppID>\.
LocalService column - in the registry, the LocalService key will be written in HKCR\AppID\<GUID_AppID>\.
ServiceParameters column - in the registry, the ServiceParameters key will be written in HKCR \ AppID \ <GUID_AppID> \.
DllSurrogate column - the DllSurrogate key will be written to HKCR\AppID\<GUID_AppID>\ in the registers.
ActivateAtStorage column - in the registry, the ActivateAtStorage key will be written in HKCR\AppID\<GUID_AppID>\. If the value of this field is 0, the ActivateAtStorage key will not be written to the registry. If the value of this field is 1, the ActivateAtStorage key will take the value Y (“ActivateAtStorage” = “Y”).
RunAsInteractiveUser column - the RunAs key will be written to HKCR\AppID\<GUID_AppID>\ in the registry. If the value of this field is 0, the RunAs key will not be written to the registry. If the value of this field is 1, the RunAs key will take the value InteractiveUser (“RunAs” = “Interactive User”).
Observation: The AppId table does not know how to register the Default key in HKCR\AppID\<GUID_AppID>\. If this key has a certain value, you must register it from the Registry table.
Registry
This table contains the registry information required for the applications.
Registry Table Columns:
Registry - the primary key that uniquely identifies the line
Root
- the predefined section of the registry
- Root can have one of the following values:
0 = HKEY_CLASSES_ROOT
1 = HKEY_CURRENT_USER
2 = HKEY_LOCAL_MACHINE
3 = HKEY_USERS
Key - the path of the registry to be created
Name
- the name of the register to be created
- If this column is null, the date in the Value column is written in the default register of this register.
Value - the data contained in the register
Component
- foreign key in the Component table
- this component controls the creation of the register
RemoveRegistry
RemoveRegistry contains information that the application needs to delete during installation.
RemoveRegistry Columns:
RemoveRegistry - unique identifier for the line
Component
- the foreign key in the Component table
- this component controls the deletion of the register referred to in the entry
Root - can have one of the following values:
0 = HKEY_CLASSES_ROOT
1 = HKEY_CURRENT_USER
2 = HKEY_LOCAL_MACHINE
3 = HKEY_USERS
Key - the path of the registry to be deleted
Name - the name of the registry to be deleted
Advanced Installer offers an easy way to add/edit your registry entries from the Registry Page.
INI Files
Initialization files are configuration files that contain easily modifiable settings for applications.
The INI file format is:
[section 1]
; comments on section 1
Var1 = abc
Var2 = 123
[section 2]
; comments on section 2
Var1 = 321
Var2 = xyz
Each section declaration begins with “[“ , and ends with “]”
Parameters are in the form var1 = abc, and are made up of a key (var1), the sign = and a value (abc).
All lines starting with comments are considered and ignored; Windows Installer ignores all lines starting with a semicolon (;)
Specific Tables for INI Files
IniFile
This table contains the information needed to set up an INI file.
IniFile | FileName | DirProperty | Section | Key | Value | Action | Component |
IniFile Columns:
IniFile - the primary key for this table
FileName - the name of the .ini file where the information will be written
DirProperty - the directory path that contains the .ini file; this property can be the name of a directory in the Directory table, a property set by a search system, or any other property that represents a path.
If this field is left blank, the INI file is created in the directory specified by the WindowsFolder property.
Section- section of the INI file
Key - key in sections
Value - the value to be written
Action - the type of changes to be made:
- 0 - create or update an INI file
- 1 - creates an entry in an INI file (only if the entry does not already exist)
- 3 - create a new entry or update an entry that already exists with a value, separating it with:
Component - foreign key in the first column of the Component table, and refers to the component that controls the installation of values from the INI file
RemoveIniFile
This table contains the information that the application needs to delete from an INI file
RemoveIniFile | FileName | DirProperty | Section | Key | Value | Action | Component |
RemoveIniFile Columns:
RemoveIniFile - the primary key for this table
FileName - the name of the .ini file from which the information will be deleted
DirProperty - the directory path that contains the .ini file; this property can be the name of a directory in the Directory table, or a property set by a search system or any other property that represents a path.
Section - section of the INI file
Key - key in sections
Value - the value to be deleted (mandatory when the Action field is 4)
Action - the type of changes to be made:
2 - delete the entry from the INI file
4 - delete a value from an entry in the INI file
Component - the foreign key in the first column of the Component table, which refers to the component that controls the deletion of values from the INI file
Notes: The information in the INI file is deleted when the attached component is selected for uninstallation.
If the Directory column is empty, the location of the INI file is the one specified by the WindowsFolder property.
Deleting the last value in a section leads to deleting the respective section. There is no other solution to erase an entire section than to erase all its values.
Caution
- The Windows operating system uses a number of INI files to set up various configurations.
- These files are WIN.INI, SYSTEM.INI, PROTOCOL.INI, PROGMAN.INI, CONTROL.INI, WINFILE.INI, MSMAIL.INI, SHARED.INI and SCHDPLUS.INI.
- Some applications add sections and entries to the WIN.INI file, and INI files to the Windows directory. It is important to take great care when adding/deleting values from these files.
Advanced Installer makes it easy to add INI files, edit INI files, and offers an advanced solution for importing multiple INI files into the project.
Shortcuts
Shortcuts are pointers to certain files and can be placed on the desktop or other locations.
Classification of shortcuts
A. Advertised
- When running an advertised shortcut, Windows Installer first checks that all the components of the respective feature are installed ( before running the file).
- The target of the shortcut must be present in the package.
B. Non-advertised
- When running a non-advertised shortcut, Windows Installer does not check if all the components of the respective feature are installed (before running the file).
- A non-advertised shortcut can launch any file, regardless of whether it is installed by the current package, already exists on the system or is on another computer. In practice, the idea is that if the target is present in the package, the shortcut must be advertised.
Shortcuts specific tables
Shortcut Table
This table contains information that the package needs to create shortcuts.
Shortcut Table Columns:
Shortcut - the key that uniquely identifies this entry in the database
Directory: - a foreign key in the first column of the Directory table
- this column specifies the directory where the shortcut is created
Name: - the name of the shortcut as it appears on the system
Component:
- a foreign key in the first column of the Component table
- Windows Installer uses the status of the component to determine if the shortcut was created or deleted
- this component must have a valid key for the shortcut being created; if the target column contains the name of a feature, the file that the shortcut launches is the “key” file to that component.
Target:
- the target of the shortcut ( the file it calls )
- for an advertised shortcut, this column must be a foreign key entered in the first column of the Feature table; the file executed by the shortcut is the key file of the component listed in the Component column. When the shortcut is run, Windows Installer checks if all the components in that feature are installed before running the file.
- for non-advertised shortcuts, Windows Installer evaluates this field as a formatted character string. The field must contain references recognized by Windows Installer (property names to be passed between “brackets” []), which will expand in the path to files / directories.
Arguments: - a list of arguments needed for the shortcut
Description: - a short description of the respective shortcut
Hotkey:
- the hotkey of the respective shortcut
- must be a positive number
- it is recommended not to be set by the packager, to avoid conflicts with the existing shortcuts on the system
Icon: - a foreign key in the first column of the Icon table
IconIndex - the icon index
- must be a positive number
ShowCmd - how to display the shortcut run executable window
- one of the following values can be used
1 - ShowNormal
2 - ShowMaximized
3 - ShowMinimazed
WkDir:
- the name of a property that contains the path of the shortcut working directory
- preferably the directory where the shortcut target is located
Shortcuts can be easily created with Advanced Installer -- and easily modified.
Fonts
Fonts are types of recordable files. The Font table contains information for registering fonts on the system.
The Font table has the following columns:
File_ - foreign key from the File table. It is recommended that the registered font is located in the FontsFolder (C:\Windows\Fonts)
FontTitle (Font name) - it is recommended to leave this column blank for True Type fonts because the installer can place the correct name from reading the title in the file. The title entered must be identical to the font name in the file. For fonts that do not have the names embedded in the file, this column must be completed (eg .fon files)
When installing an MSI, this table creates a registry in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts - with the font name and the value of the file.
Advanced Installer automatically detects and registers fonts, also offering an easy GUI to control this.
Services
Services are programs that run individually in the background. This can be said of many programs, such as anti-viruses. The difference is that the services load and run regardless of whether someone logs into the system or not, unlike a program launched from the StartUp folder.
You can view Services using the MS Configuration Utility and running the msconfig.exe executable.
It offers rather limited information, in the sense that you can only see which services are turned on and which are not.
Another way to view the service is through services.msc, equivalent to the Control Panel\Administrative Tools\Services.
This method provides much more information about services, such as name, short description, status, etc.
Microsoft has assigned a display name for each service. It is the name that appears in the name column of the Windows Services window.
Attributes:
Service Name: The name of the service
Process Name/Path to execute: The name of the process that runs when the service is enabled.
Dependencies: The list of additional services that are required when the service is running.
These services are found “physically” in the machine registry: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services.
Classification of services
- automatic (start with the operating system)
- manuals (are started by applications/users)
Service status:
- Start
- Stop
- Disable
Services-specific tables
ServiceInstall
This table is used to install services:
ServiceInstall | Name | DisplayName | ServiceType | StartType | ErrorControl | LoadOrderGroup | Dependencies | StartName | Password | Arguments | Component | Description |
ServiceInstall Columns:
Name
- the name of the service, internal to windows
- must have a maximum of 256 characters
Display
- the name that appears to the user
- maximum 256 characters
ServiceInstall - primary key for this table
ServiceType
- the type of service
- accepted values:
0x00000010 - Win32 service, running its own process
0x00000020 - Win32 service, which streamlines a process
0x00000100 - Win32 service, which interacts with the desktop
StartType
- this column specifies when the process starts
- These are the accepted values:
2 - the service starts with the system (automatic)
3 - the service starts on request (manual)
4 - specify a service that cannot be started (disable)
ErrorControl
- this column specifies the action that Windows Installer must take if the service fails
to start
- accepted values:
0x00000000 - creates an error log and continues with the service start operation
0x00000001 - creates an error log, displays a message, and continues with the service start operation
0x00000003 - creates an error log (if possible) and restarts the system
LoadOrderGroup
- this column contains the order in which services will be started within a service group (if our service is also part of it)
- when left empty, it means that our service is not part of any group
Dependencies
- a list of services that must be started before starting the service from this entry
- services are separated by [~]
StartName
- the service starts with the name specified in this column
- if it has no value then the service uses the LocalSystem account to run
Password - the password of the account with which the service runs
Arguments - this column contains any arguments needed by the service to run
Component
- a foreign key in the Component table
- to create the service attached to this component, it must have the executable that is the basis of the service as key
Description - a description of the service being created
Virtually all the values populated by these columns correspond to the values in the registry:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Service_Name
From this table, you can install certain types of drivers, including Non-Plug & Play. These drivers are entered in the table similar to the services, except that in the column for the type of service (ServiceType column) other values are entered as follows:
0x00000001 - driver service
0x00000002 - file system driver service
The startup type of the driver also differs from the services. Non-plug & play drivers have 4 boot modes: Automatic, Boot, Demand, System. These startup types can be set from the table as for services in the StartType column as follows:
- Automatic - set the value to 2
- Boot - value 0
- Demand - value 3
- System - value 1
If you want the driver to be set as disabled, then add the value 0 in the StartType column.
On the machine, you can check the functionality of this type of driver from the DeviceManager to Non-Plug & Play Drivers (to see Non-Plug & Play Drivers, you must first access the View\Show hidden devices menu).
Attention: With the help of this table, the service/driver is installed but it does not start. That is why it is mandatory to use it along with the ServiceControl table.
For automatic services, you must perform an installation control service (start only for automatic ones) and a service control for uninstallation (stop and delete, both for automatic and manual ones).
ServiceControl
This table is used to control the installation and uninstallation of services.
ServiceControl Columns:
ServiceControl - the primary key of this table
Name - the name of the service to be controlled
Event
- the operation to be performed on the service
- when a service is stopped, all services that depend on it are also stopped
- when a service is deleted, Windows Installer stops it
- values accepted at installation only:
1 - the service starts
2 - the service stops
8 - the service is deleted
- values accepted only when uninstalling:
16 - the service starts
32 - the service stops
128 - the service is deleted
Arguments
- a list of arguments for starting services
- arguments are separated by the reserved character [~]
Wait
- tells the system to “wait” before an actionLeaving this field blank or entering the value 1 tells Windows Installer to wait a maximum of 30 seconds for the service to follow an action
- it can be used when you want to allow additional time for critical events to return an error code
- the value 0 means that Windows Installer waits until SCM (Service Control Manager) reports that the service is in a standby state
Component - foreign key in the Component table
Note: With the Name column, you can start, stop, or delete services not created by our package.
With Advanced Installer you can easily install, control and configure Windows native services from the Services Page. More information about configuring services using Advanced Installer can also be found here, and in the service control properties.
ODBC (Open DataBase Connectivity)
As its name implies, an ODBC (Open DataBase Connectivity) connects your application to a variety of database management systems. Essentially, it allows applications to access a database (such as Access databases, dBase or Excel, etc.).
Classification of ODBC
- UserDSN: is a “data source” that is specific to a particular user; it is saved on the machine but is only available to the user who created it.
UserDSN ODBCs are registered in the user-specific registry:
HKEY_CURRENT_USER\ODBC\ODBC.INI\Odbc Data sources
- SystemDSN: unlike UserDSN, it is saved locally but is not specific to a user.
Using a SystemDSN, any user who connects to a computer is allowed to access the data source.
SystemDSN ODBCs are registered in the machine-specific registry:
HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\Odbc Data sources
- Drivers are libraries that implement functions for ODBC API; each driver is specific to a database management system.
Drivers practically play the role of a “translator” between an application and a database. The main utility of these drivers is that they allow us to interact with the databases, without the need to have a client program (provided by the database manufacturer).
ODBCs are managed through the ODBC Data Source Administrator, which is accessed from the Control Panel\Administrative Tools\Data Sources (ODBC).
As specified above, ODBC information is stored in the registry:
HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI
HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI
HKEY_CURRENT_USER\ODBC\ODBC.INI
HKEY_CURRENT_USER\ODBC\ODBCINST.INI,
Keys with ODBCINST.INI contain information about the drivers installed on the machine, and those with ODBC.INI contain information about the DSN on the machine.
You can also access information about ODBCs in the INI, ODBC.INI, and ODBCINST.INI files present in C:\WINDOWS.
ODBC specific tables
ODBCDataSource
This table contains the data sources related to the application.
ODBCDataSource Columns:
DataSource - input identifier
Component - foreign key in the Component table
Description - description of the source data
DriverDescription - the driver associated with the data source
Registration - how the data source is registered:
0 = per machine
1 = per user
ODBCSourceAttribute
This table contains information about the data attributes of the sources.
DataSource - datasource identifier, the primary key for the table
Attributes - attribute of the source data, the primary key for the table
Value - the value of the attribute
The ODBCDataSource and ODBCSourceAttribute tables install the DSN on the machine with all its information (both of these tables must be populated for a DSN to be installed).
The changes made by these two tables can be found in the
HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\DSName.
Note: A DSN from the corresponding tables can be placed even if the driver associated with the DSN is not in the package.
ODBCDriver
This table contains the ODBC drivers that belong to the application.
Driver - the driver identifier, the primary key for the table
Component - the foreign key in the component table
Description - the driver description
File - the dll file that generates the driver, foreign key in the File table
File_Setup - a driver-specific dll setup file, foreign key in the File table
ODBCAttribute
This table contains information about the attributes of drivers and translators.
Driver - the driver identifier, primary key for this table, foreign key in the table
Attributes - the attribute name, the primary key for the table
Value - the value of the attribute
The changes that these two tables make on the machine are the following:
- HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\Driver_name - the entry written from the ODBCAttribute table, that contains all the driver description registry.
- HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers - where a string-type registry is created with the name of the driver and the value Installed.
- The C:\Windows\ODBCINST.INI file is altered with the extra driver.
To check a driver (if it is installed correctly), you can go to the Control Panel\Administrative Tools\Data Source (ODBC).
For further testing, you can add a DSN (user or system) by choosing the respective driver to set the DSN.
Note: An ODBCDriver cannot be set from the corresponding tables unless the required files (DriverDll and SetupDll) are in the package.
ODBCTranslator
This table contains ODBC translators that belong to the application.
Translator - the name of the translator, the primary key for the table
Component - the foreign key in the component table
Description - the description of the translator
File - the dll file, the foreign key in the File table
File_Setup - the dll setup file, the foreign key in the File table
The ODBCTranslator table writes in the following registry:
- HKLM\SOFTWARE\ODBC\ODBCINST.INI
- HKLM\SOFTWARE\ODBC\ODBCINST.INI\ODBC Translators
You can find a translator in the DSN (Administrative Tools\Data Sources) dialog where you want to load the translator. The display mode of a translator differs depending on the driver.
Easily manage your ODBC connections with Advanced Installer by using the ODBC Page.
System variables
System variables are strings that replace longer data references.
They already exist defined on the system and you can view them using the “set” command in CMD.
You can also access them from System Properties\Advanced\Environment Variables.
Classification:
User variables - found in: HKEY_CURRENT_USER\Environment
System variables - found in:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
The system variables can be used directly in the package, using the reference type [%ENVVAR].
You can also define new variables to be used by the runtime package.
Tables specific to system variables
Environment
Environment Table columns:
Name: The name of the system variable: the system variable is written or deleted depending on the symbols that appear in front of the name -- there is no specific order for these symbols.
Prefix | Description |
= | Creates the variable if it does not exist, and sets it to the given value. If the variable already exists, just set it to the given value. |
+ | Creates the variable if it does not exist, and sets it to the given value. If it already exists, it has no effect on the value of the variable. |
- | Deletes the variable when the component is uninstalled. This symbol can be combined with any prefix. |
! | Deletes the variable during the component installation. Windows Installer deletes a variable during installation if the name and value of the variable match the entries in the Environment table. If you want to delete a system variable regardless of its value, it is recommended to use the syntax "!", and leave the Value column blank. |
* | This prefix is used by Microsoft Windows NT / 2000 to indicate that the name refers to a system variable (not a user). If no asterisk is present, Windows Installer writes the variable as a user variable. Microsoft Windows 95/98 ignores the asterisk and adds the variable to the autoexec.bat file. This symbol can be combined with any other prefix. It is recommended that packages installed "per-machine", write only system variables (not user), using the * symbol in the name. |
=- | The variable is set at installation and deleted at uninstall. This is normal behavior. |
!- | Deletes variables when installing or uninstalling. |
=+, !+, != | These prefixes are not valid. |
Value:
- this column contains the value to be set as a formatted string;
- if this column is empty, the variable is deleted; if the column is empty and the “-” symbol appears in the name column, the variable is deleted when the component is deleted.
- to add a new value to an already existing one, the value in this column must end with the prefix “~” and the separation character “;”. ex: [~]; Value
- to add a new value to an already existing one, the value in this column must begin with the suffix “~”, accompanied by the separate character “;” ex: Value; [~]
- if the string [~] is not present in this field, the value in this column
represents the entire value to be set or deleted.
- each row contains only one value; values such as Value; Value [~] are not recommended due to unpredictability
- if the field name has the character “+” as a prefix, then you must use the string [~] in the value column; the two must be used together
Environment: - the key that uniquely identifies the record
Component: - a foreign key from the first column of the Component table; this column controls the installation of the system variable through the component
The environment variables can be easily managed in Advanced Installer in the Environment Variables Page.
Properties
Properties are global variables that Windows Installer uses during installation, with values defined either in the package or by the user.
Property classification
Private properties:
- used internally by Windows Installer and defined directly in the package
- their name includes lowercase letters
- the value of these properties cannot be overwritten at installation by using commands
Public properties:
- defined inside the package, they can be changed by commands, applying a transform, or through a graphical interface.
- their names must not contain lower case letters
- usually, they are set during installation (eg INSTALLEVEL)
Restricted public properties:
- for security reasons, the author of a package may restrict the user from modifying public properties
- if all of the following conditions are true, a user who is not a system
administrator may overwrite an approved list of restricted public properties
- The system is not Windows 2000.
- The user is not a system administrator.
- The package is installed with elevated privileges.
There is a predefined list of restricted properties and, listed below, are the most important:
A software packager can extend this list (by adding these properties as the value in this property) to include other public properties with the “SecureCustomProperties” property.
These five properties are required in a package:
- ProductCode - a unique identifier of the GUID package
- ProductLanguage - the language that the installer uses in the LANGID graphical interface
- Manufacturer - the name of the package manufacturer
- ProductVersion - the application version in string format (form: major.minor.build = 255.255.65535)
- ProductName - the name of the application to be installed (maximum 63 characters)
The required properties must be listed in the Property tables. Properties that have a null value are not listed in this table. Instead, they can be set directly through the program, custom actions, or the command line. You can also use Properties in conditional statements.
The Most Common Properties used in Packages
ALLUSERS
The ALLUSERS property determines where the package configurations are stored.
Windows NT/Windows 2000 | ALLUSERS is not set. (ALLUSERS="") | ALLUSERS = 1 | ALLUSERS = 2 |
User access privileges. | Per-user installation using folders in the user's personal profile. | Not valid; returns an error stating the user does not have enough access privileges to install the application. | Per-user installation using folders in the user's personal profile. |
Administrator access privileges. | Per-user installation using folders in the user's personal profile. | Per-machine installation using folders in "All Users" profile. | Per-machine installation using folders in "All Users" profile. |
If the ALLUSERS property is not set, Windows Installer performs a per-user installation.
ARPNOREMOVE
If this property is set, the remove button will not appear in Add\Remove Programs. Its default value is 0.
ARPNOREPAIR
When this property is set, the repair button in Add\Remove Program is not displayed. The default value is 0.
ARPNOMODIFY
By setting this property, the change button in Add\Remove Program is not displayed. The default value is 0.
ARPSYSTEMCOMPONENT
When this property is set, the package is not displayed in Add\Remove Program. The default value is 0.
INSTALLEVEL
The INSTALLEVEL property sets the base level for all features whether they are installed or not; a feature is installed only if the value entered in the LEVEL field (in the Feature table) is less than or equal to the INSTALLEVEL property value.
If no value is specified, then it has the default value 1, and if the value in the LEVEL field is 0, that feature is neither installed nor displayed in the graphical interface.
LIMITUI
Setting this property leads to a very limited (basic) graphical interface. The default value is 0.
REBOOT
Setting this property suppresses the system restart request.
REBOOT value | Description |
Force | The UI always prompts the user with an option to reboot at the end of the installation. If there is no user interface, the system automatically reboots at the end of the installation. |
Suppress | Suppress prompts for a reboot at the end of the installation. The installer still prompts the user with an option to reboot during the installation whenever it encounters the ForceReboot action. If there is no user interface, the system automatically reboots at each ForceReboot. Reboots at the end of the installation are suppressed (for example the ones caused by an attempt to install a file in use). |
ReallySuppress | Suppress all reboots and reboot prompts initiated by ForceReboot during the installation. Suppress all reboots and reboot prompts at the end of the installation. It suppresses both the reboot prompt and the reboot itself. For example: It suppresses reboots caused by an attempt to install a file in use at the end of the installation. |
ROOTDRIVE
Setting this property specifies the default drive of the application installation location. The value of this property must end with “\”, for example “C:\”.
More information about Windows Installer Properties and how you can edit them with Advanced Installer can be found here.