Blog
Authoring Secured Installations
MSI Special Tips , Adherence to the following guidelines when authoring a Windows Installer package helps maintain a secure environment during installation:
Administrators should install managed applications into a target installation folder for which non-admin users do not have change or modify privileges.
Make any property set by the user a public property. Private properties cannot be changed by the user interacting with the user interface.
Do not use properties for passwords or other information that must remain secure. The installer may write the value of a property authored into the Property table, or created at run time, into a log or the system registry.
When the installation requires the installer to use elevated privileges, use Restricted Public Properties to restrict the public properties a user can change. Some restrictions are commonly necessary to maintain a secure environment when the installation requires the installer to use elevated privileges.
Avoid installing services that impersonate the privileges of a particular user because this may write security data into a log or the system registry. This creates potential for a security problem, password conflict, or the loss of configuration data when the system is restarted. For details, see ServiceInstall table.
Use the LockPermissions table to secure files, registry keys, and created folders in a locked-down environment.
Add a digital signature to the installation to ensure the integrity of the files. For details, see Digital Signatures and Windows Installer and Authoring a Fully Verified Signed Installation.
Author the Windows Installer package such that if the user is denied access to resources, the setup fails in a manner that maintains a secure environment. Check the user’s access privileges and determine whether there is sufficient disk space before installation begins. Commonly, the installer should only display a browse dialog box if the current user is an administrator or if the installation does not require elevated privileges. For details, see Source Resiliency.
Use Secured Transforms to store transforms in a secure file system locally on the user’s computer. This prevents the user from having write access to the transform.
For information on how to secure media sources of managed applications, see Source Resiliency.
Use the Security Summary Property to indicate whether the package should be opened as read-only. This property should be set to read-only recommended for an installation database and to read-only enforced for a transform or patch.
The installer runs custom actions with user privileges by default in order to limit the access of custom actions to the system. The installer may run custom actions with elevated privileges if a managed application is being installed or if the system policy has been specified for elevated privileges.
Use the DisablePatch policy to provide security in environments where patching must be restricted.
Use the AppId table to register common security and configuration settings for DCOM objects.
Starting with Windows Installer 3.0, User Account Control (UAC) Patching enables non-administrator users to patch applications installed in the per-machine context. UAC patching is enabled by providing a signer certificate in the MsiPatchCertificate table and signing patches with the same certificate.
CRC check during an Installation ( MSI Special Tips)
A Cyclic Redundancy Check (CRC) of files is available with Windows Installer version 2.0 or later. CRC checking is an error-checking mechanism, similar to a checksum, that enables an application to determine whether the information in a file has been modified. After the Windows Installer finishes copying a file, it gets a CRC value from both the source and destination files. The installer checks the original CRC stamped into the file and compares this to the CRC calculated from the copy. The CRC check fails if the original CRC value is non-null and is different from the CRC calculated on the copy. If the original CRC is null, no check occurs.
The Windows Installer does a CRC check on a file in the following cases:
If the MSICHECKCRCS property is set and msidbFileAttributesChecksum is included in the Attributes field of the file’s record in the File table. The installer does the CRC check once after installing, duplicating, or moving the file.
If the MSICHECKCRCS property is set and msidbFileAttributesChecksum is included in the Attributes field of the file’s record in the File table, the installer does a CRC check after patching the file.
If the msidbFileAttributesChecksum is included in the Attributes field of the file’s record in the File table, the installer does a CRC check before binding images.
If the check fails before binding an image, the installer reports the following two errors in the log file and continues the installation without binding the file.
Code | Message |
2941 | Unable to compute the CRC for file [2]. |
2942 | BindImage action has not been executed on [2] file. |
If the check fails after an uncompressed file had been copied, duplicated, or patched, the installer reports the following error. This error is also reported if the check fails after a compressed file is copied. If the file has the msidbFileAttributesVital attribute, the file is considered vital to the installation and the user gets the option to retry or cancel the installation. If the file is marked as non-vital in the Attributes column of the File table, the user may ignore the error and continue, retry, or cancel the installation.
Code | Message |
1331 | Failed to correctly copy [2] file: CRC error. |
Note that only uncompressed files are moved. If the check fails after an uncompressed file is moved, the installer displays the following error. If the file has the msidbFileAttributesVital attribute, the file is considered vital to the installation and the installation fails. If the file is marked as non-vital in the Attributes column of the File table, the user gets the option to cancel or to ignore the error and continue the installation.
Code | Message |
1332 | Failed to correctly move [2] file: CRC error. |
If the check fails after an uncompressed file is patched, the installer displays the following error. If the file has the msidbFileAttributesVital attribute, the file is considered vital to the installation and the installation fails. If the file is marked as non-vital in the Attributes column of the File table, the user gets the option to cancel or to ignore the error and continue the installation.
Code | Message |
1333 | Failed to correctly patch [2] file: CRC error. |
Installing Permanent Components, Files, Fonts and Registry Keys ( MSI Special Tips)
To install a file, font, or registry key so that it is not removed when the product is uninstalled, the entire component containing the file, font, or registry key must be made permanent. To make a component permanent, set msidbComponentAttributesPermanent in the Attributes column of the Component table.
Note that the installer removes a registry key after removing the last value or sub-key under the key. To prevent an empty registry key from being removed on uninstall, write a dummy value under the key one need keep, and enter + in the Name column of the Registry table.
Adding and removing an Application and leaving no trace in the registry ( MSI Special Tips)
If an application must be registered, author the installation package as described in the section Adding and Removing Registry Keys on the Installation or Removal of Components. Registration is used by the installer for advertisement and by the Add or Remove Programs feature in Control Panel. If an application is not registered, it cannot be advertised, and is not listed in the Add or Remove Programs feature in Control Panel.
One can omit registering an application by removing the RegisterProduct Action, RegisterUser Action, PublishProduct Action, and PublishFeatures Action from the InstallExecuteSequence Table and AdvtExecuteSequence Table. All of these actions must be removed, or some trace of the application may remain in the registry. Removing all of these actions prevents the application from being listed in the Add or Remove Programs feature in Control Panel, and prevents the advertisement of the application. Removing all of these actions also prevents the application from being registered with the Windows Installer configuration data. This means that one cannot remove, repair, or reinstall the application by using the Windows Installer Command-Line Options, or the Windows Installer application programming interface (API).
To hide an application from the Add or Remove Programs feature in Control Panel and still be able to use the Windows Installer to manage an application, leave the registration actions in the sequence tables, and set the ARPSYSTEMCOMPONENT Property in the Property Table to 1 (one). The application does not appear in the Add or Remove Programs feature, but one can use the Windows Installer to install-on-demand, uninstall, repair, and reinstall the application.
Changing the Target Location for a Directory ( MSI Special Tips)
If possible, the best way to specify the target location for a directory is to author the Directory Table in the installation package to provide the correct location.
If one needs to change the directory location at the time of the installation, then he has the following options:
Specify the location of a directory by setting the value of a Public Property on the command line. During the CostFinalize Action, the internal directory paths used by the installer are updated to the value of properties listed as keys in the Directory Table.
Specify the location of a directory by using a custom action. If the custom action is to run before the CostFinalize Action, one can use a Custom Action Type 51 to set the value of a property from a formatted text string. If the custom action runs after the CostFinalize Action, one can use a Custom Action Type 35 to set the value of the directory path from a formatted text string. Custom actions that change one of the System Folder Properties should be included in both the execution sequence tables (InstallExecuteSequence Table or AdminExecuteSequence Table), and the user interface sequence tables (InstallUISequence Table and AdminUISequence Table) so that the folder is changed during both full UI and basic UI installations.
If the installation is running a full UI, one can use MsiSetTargetPath or the SetTargetPath ControlEvent to set the directory path. Check the ProductState Property to determine whether the product that contains this component is already installed before calling MsiSetTargetPath or the SetTargetPath ControlEvent. Do not attempt to change the target directory path if some components that use that path are already installed for the current user or a different user.
The following restrictions apply to all of the above options:
- Do not attempt to change the target directory path if some components that use the path are already installed for the current user or for a different user.
- Do not attempt to change the target directory path during a Maintenance Installation.
Authoring a Large Package ( MSI Special Tips)
Use this guideline to author a Windows Installer package that contains more than 32767 files.
If the Windows Installer package contains more than 32767 files, one must change the schema of the database to increase the limit of the following columns:
- The Sequence column of the File table.
- The LastSequence column of the Media table.
- The Sequence column of the Patch table.
To increase the limit of a database column
Export the table to an .idt file. For details, see Msidb.exe, Export Files, and Importing and Exporting.
Edit the .idt file to change the column type from i2 to i4, or from I2 to I4.
Export the _Validation table to an .idt file.
Edit the .idt file to change the values in the MaxValue column of the _Validation table to accommodate the increased column widths.
Import the .idt files back into the database.
Note that transforms and patches cannot be created between two packages with different column types
Reducing the size of an .MSI file ( MSI Special Tips)
Developers of Windows Installer packages may notice their .msi files getting larger than expected after repeated edits and saves. Windows Installer .msi files are compound files that contain storages and streams, and have some of the same storage limitations as OLE document files. If one edits and save the same .msi file over and over, it creates wasted storage space in the file. This only affects authors of .msi files and has no effect on Windows Installer users. Developers may want to remove this wasted storage space before shipping their final .msi file.
To remove wasted storage space and reduce the final size of .msi files, one has the following options:
Export all of the tables in the database to .idt files, and then import those into a new database. This produces the most compact storage possible.
Use a software utility for compacting the storage space of OLE document files.
Resolving Advertised Shortcuts with IShellLink:: Resolve ( MSI Special Tips)
In certain cases with Microsoft® Windows® 98 and in the Internet Explorer 4.01 shell, it may be necessary to launch an installation-on-demand of an application by calling the system method IShellLink::Resolve on an advertised shortcut of an application. By default, a call to IShellLink::Resolve on an advertised shortcut does not install the application. To override the default, and allow this type of installation-on-demand, add the name of the executable file as the name portion of a value pair under one or both of the following registry keys:
HKLM\Software\Microsoft\Windows\CurrentVersion\Installer\ResolveIOD
HKCU\Software\Microsoft\Windows\CurrentVersion\Installer\ResolveIOD
Removing Stranded Files
If a file that should have been removed from the user’s computer remains installed after running an uninstall, the installer may not be removing the component containing the file for one or more of the following reasons:
The msidbComponentAttributesPermanent bit was set for the component in the Attributes column of the Component table.
No value was entered for the component in the ComponentId column of the Component table.
The component is used by another application or feature that is still installed.
There is a condition specified in the Condition table that enables a feature during installation and disables the feature during uninstallation.
The key file for the component has a previous reference count under HKLM\Software\Microsoft\Windows\CurrentVersion\SharedDLLs.
The component is installed in the System folder and any file in the component has a previous reference count under HKLM\Software\Microsoft\Windows\CurrentVersion\SharedDLLs.
The Windows Installer does not remove any files or registry keys that are protected by Windows Resource Protection (WRP) on Windows Vista. On Microsoft® Windows XP® and ® Windows 2000®, the installer does not remove any files that are protected by Windows File Protection (WFP). If a component’s key path file or registry key is protected by WFP or WRP, the installer does not remove the component.
Note: Because Windows Installer does not install, update, or remove any resource that is protected by Windows Resource Protection on Windows Vista one should not include protected resources in an installation package. Instead, use only the supported resource replacement mechanisms described in the Windows Resource Protection section.
Searching for Existing Applications, Files, Registry Entries, or .INI File Entries
Windows® Installer can search for a specific file or directory during an installation. File or directory searches are used to determine whether a user has already installed a version of an application.
AppSearch Action searches a user system for file signatures that are specified in the AppSearch Table. If the AppSearch action finds an installed file or directory with the specified signature, it sets a corresponding property, also specified in the AppSearch Table, to the location of the file or directory. When searching for a file, the file signature must also be listed in the Signature Table. If a file signature is listed in the AppSearch Table and is not listed in the Signature Table, the search looks for a directory, registry entry, or .ini file entry.
To expedite the search of a user computer, the Installer queries the following locator database tables in the order listed for a suggested search location:
If the file signature is listed in the CompLocator Table, the suggested search location is the key path of a component. If the signature is not listed in this table or not installed at the suggested location, the Installer queries the RegLocator Table for a suggested location.
If the file signature is listed in the RegLocator Table, the suggested search location is a key path written in the user registry. If the signature is not listed in this table or not installed at the suggested location, the Installer queries the IniLocator Table for a suggested location.
If the file signature is listed in the IniLocator Table, the suggested search location is a key path written in an .ini file present in the default Windows directory of a user system. If the signature is not listed in this table or not installed at the suggested location, the Installer queries the DrLocator Table for a suggested location.
If the file signature is listed in the DrLocator Table, the suggested search location is a path in the user directory tree. The depth of subdirectory levels to search below this location is also specified in this table.
How to delay a Custom Action?
(How to use an .EXE inside .MSI Script without installing it?)
The purpose of a deferred execution custom action is to delay the execution of a system change to the time when the installation script is executed. This differs from a regular custom action, or a standard action, in which the installer executes the action immediately upon encountering it in a sequence table or in a call to MsiDoAction. A deferred execution custom action enables a package author to specify system operations at a particular point within the execution of the installation script. The installer does not execute a deferred execution custom action at the time the installation sequence is processed. Instead the installer writes the custom action into the installation script. The only mode parameter the installer sets in this case is MSIRUNMODE_SCHEDULED. See MsiGetMode for a description of the run mode parameters.
A deferred execution custom action must be scheduled in the execute sequence table within the section that performs script generation. Deferred execution custom actions must come after InstallInitialize and come before InstallFinalize in the action sequence. Custom actions that set properties, feature states, component states, or target directories, or that schedule system operations by inserting rows into sequence tables, can in many cases use immediate execution safely. However, custom actions that change the system directly, or call another system service, must be deferred to the time when the installation script is executed. Because the installation script can be executed outside of the installation session in which it was written, the session may no longer exist during execution of the installation script. This means that the original session handle and property data set during the installation sequence is not available to a deferred execution custom action. Deferred custom actions that call dynamic-link libraries (DLLs) pass a handle which can only be used to obtain a very limited amount of information, as described in Obtaining Context Information for Deferred Execution Custom Actions.
Note that deferred custom actions, including rollback custom actions and commit custom actions, are the only types of actions that can run outside the users security context.
Why not to use Self Registration?
Self registering of a file causes the MSI to loose its reference because the MSI will not be able to register the data according to its own, thus leading to the creation of unwanted junk. This may not affect the installation process but may lead to unclean uninstallation. Installation package authors are strongly advised against using self registration. Instead they should register modules by authoring one or more tables provided by the installer for this purpose. Many of the benefits of having a central installer service are lost with self registration because self-registration routines tend to hide critical configuration information. Reasons for avoiding self registration include:
Rollback of an installation with self-registered modules cannot be safely done using DllUnregisterServer because there is no way of telling if the self-registered keys are used by another feature or application.
The ability to use advertisement is reduced if Class or extension server registration is performed within self-registration routines.
The installer automatically handles HKCR keys in the registry tables for both per-user and per-machine installations. DllRegisterServer routines currently do not support the notion of a per-user HKCR key.
If multiple users are using a self-registered application on the same computer, each user must install the application the first time they run it. Otherwise the installer cannot easily determine that the proper HKCU registry keys exist.
The DllRegisterServer can be denied access to network resources such as type libraries if a component is both specified as run-from-source and is listed in the SelfReg table. This can cause the installation of the component to fail to during an administrative installation.
Self-registering DLLs are more susceptible to coding errors because the new code required for DllRegisterServer is commonly different for each DLL. Instead use the registry tables in the database to take advantage of existing code provided by the installer.
Self-registering DLLs can sometimes link to auxiliary DLLs that are not present or are the wrong version. In contrast, the installer can register the DLLs using the registry tables with no dependency on the current state of the system.
What is Active Setup?
Active setup is a process that runs automatically when a user logs in. The principle of Active Setup behavior is when a new user logs on for the first time, then the Active Setup will perform a checksum between HKLM\Software\Microsoft\Active Setup\Installed Components\ {GUID o MSI} and the HKCU\Software\Microsoft\Active Setup\Installed Components\ {GUID o MSI}; and if the GUID is not present under HKCU, then it performs all actions which are under that main hive (StubPath, Version, as described in the section below) and populates the GUID under HKCU. The main advantage of Active Setup is it performs an action only once per user with the Checksum behavior by matching the entries under HKLM and HKCU.
How is Active Setup implemented?
Create the following registry keys under the main hive:
HKLM\Software\Microsoft\Active Setup\Installed Components\ {GUID o MSI}
StubPath= [SystemFolder]msiexec /fu {Product Code of the MSI} /q
Version= {ProductVersion}
Now when each new user logs on, the operating system compares Active Setup keys between HKLM and HKCU, and runs the nominated executable if the HKCU entry is missing or the version in HKCU is less than HKLM.
To force a repair using the existing MSI where a separate Active Setup EXE is not required, you can do it this way:
Create the following key structure under HKEY_LOCAL_MACHINE hive:
HKEY_LOCAL_MACHINE\Software\Microsoft\Active Setup\Installed Components\[ProductCode]
StubPath= msiexec /fauvs {ProductCode} /qb"
How to search for Existing Applications, Files, Registry Entries or .INI file Entries?
Windows Installer can search for a specific file or directory during an installation. File or directory searches are used to determine whether a user has already installed a version of an application.
AppSearch Action searches a user system for file signatures that are specified in the AppSearch Table. If the AppSearch action finds an installed file or directory with the specified signature, it sets a corresponding property, also specified in the AppSearch Table, to the location of the file or directory. When searching for a file, the file signature must also be listed in the Signature Table. If a file signature is listed in the AppSearch Table and is not listed in the Signature Table, the search looks for a directory, registry entry, or .INI file entry.
To expedite the search of a user computer, the Installer queries the following locator database tables in the order listed for a suggested search location:
If the file signature is listed in the CompLocator Table, the suggested search location is the key path of a component. If the signature is not listed in this table or not installed at the suggested location, the Installer queries the RegLocator Table for a suggested location.
If the file signature is listed in the RegLocator Table, the suggested search location is a key path written in the user registry. If the signature is not listed in this table or not installed at the suggested location, the Installer queries the IniLocator Table for a suggested location.
If the file signature is listed in the IniLocator Table, the suggested search location is a key path written in an .INI file present in the default Windows directory of a user system. If the signature is not listed in this table or not installed at the suggested location, the Installer queries the DrLocator Table for a suggested location.
If the file signature is listed in the DrLocator Table, the suggested search location is a path in the user directory tree. The depth of subdirectory levels to search below this location is also specified in this table.
The first time the Installer finds the file signature at a suggested location, it stops searching for this file or directory, and sets the corresponding property in the AppSearch Table.
How to convert File Association info into registries?
Creating file associations using the File Associations page in Installation Expert populates the MIME and Verb tables. These tables contain advertising information used by Windows Installer to determine if self-repair is necessary for installation.
To prevent Windows Installer from self-repairing file associations, no data should exist in the MIME or Verb tables and such data should be converted into registry information. To populate the registry information about file associations for the application (including Command Verbs and File MIME types):
On the File Associations tab of Installation Expert, double click the first file association listed.
On the Extension Details tab note the values of the Extension and ProgID fields.
If there are any entries on the Command Verbs tab, double-click each entry and note the value of the Verb field.
Note any entries listed on the MIME Types tab.
On the test machine, open the Windows registry and look directly under HKEY_CLASSES_ROOT for the file associations noted in step 1 above.
Manually create the entire key and all sub keys in the Registry section of Installation Expert. If no Command Verbs or MIME Types exist for this file association, proceed to step 12. If only MIME Types exist proceed to step 10.
On the test machine, look directly under the HKEY_CLASSES_ROOT for the ProgID noted in step 2 above.
Delete the REG_MULI_SZ registry value names “command” from HKEY_CLASSES_ROOT\<ProgID>\shell\<Verb>\command for each verb noted in step 3 above. The command value contains advertising information and initiates self-repair. Do not delete the (Default) string value.
Manually create the key and all remaining sub keys in the Registry section. If no MIME Types exist proceed to step 12 below.
On the test machine, look under HKEY_CLASSES_ROOT\MIME\Database\Content Type for the MIME Types noted in step 3 above.
Manually create the key and all sub keys in the Registry section for each MIME type.
Repeat steps 1-11 for each of the file associations listed in the File Association section.
After completing the steps above, remove all file association information from the File Associations section. This enables file associations to function as expected while preventing self repair for those entry points.
How to repair corrupted files?
A corrupt file will not trigger Windows Installer to perform self-repair. This is because the Windows Installer checks only for file existence when checking a component that uses a file for its key path.
Although a corrupted file may not function properly, as long as Windows Installer can verify that the file exists at that location a self-repair will not be triggered. However, if another missing key path causes a self-repair the corrupted file will be replaced with a functioning copy from the installation source if the file is in the same feature as the component with the missing key path.
Corrupted files can be repaired by performing a manual repair of the MSI using the maintenance dialog or by running the MSI via command line with the switch /focmus. Additionally, the following information must be true for the repair to correct the corrupt file:
The file must have an internally provided checksum provided. This is done at compile time of the .DLL, .OCX, or .EXE by the program used to create that file.
The Attribute column of the File table for this file must include the attribute 1024 which indicates to the Windows Installer service that the file has a valid checksum. This attribute may need to be added manually.
How can a self-repair of a particular component be prevented?
There might be times when you need to prevent Windows Installer from initiating self-repair of a particular component. For example, your application might move files to another location as a part of its normal operation. If Windows Installer initiates a self-repair of the application, the files no longer exist when the application expects to find them. In this case turning off self-repair functionality prevents this behavior from occurring.
To turn-off self-repair functionality for a component:
On the Table tab in Setup Editor, select the Component table.
Select the ComponentID column of the component for which you want to turn off self-repair.
Press the F2 key to edit the ComponentID column.
Clear the contents of the ComponentID column.
Save and compile the installation.
If you turn off self-repair for a component that has an advertised shortcut, complete the following additional steps:
In the Shortcuts tab in Installation Expert, select the Feature containing the component that no longer has self-repair functionality.
Click the shortcut associated with the component that no longer has self-repair functionality and delete it.
Click Add and create a new shortcut to the file, making sure to clear the Advertised checkbox.
Save and compile the installation.
Deleting the ComponentID of a component prevents Windows Installer from initiating self-repair of the component. Also keep in mind that deleting the ComponentID of a component also prevents Windows Installer from uninstalling the component, as Windows Installer skips registration of any component with no ComponentID.
How to conditionally add a data to a registry value?
There are times when it is necessary to add data to an existing registry value rather than to replace the existing value. However, to prevent adding data that already exists in the registry value you must take additional steps to build this functionality into your installation. For example, you need to create a sample installation that adds “newdata” to the string registry value of HKEY_CURRENT_USERS\Software\Example registry key if the registry value does not already contain “newdata”.
First add a system search to determine the data contained in the existing registry value:
Create a new Windows Application project and complete the Product Details section as desired.
In the System Search section, click Add—>Registry. The Read Registry Value dialog appears.
Complete the fields on the Read Registry Value dialog as follows:
Property: EXISTINGVALUE
Operation: Read raw value from registry
Root: HKEY_CURRENT_USER
Key: Software\Example
Value Name: Example
Click OK to close the Read Registry Value dialog
Next, add the registry key:
In the Registry section, select the appropriate root (example: HKEY_CURRENT_USER) in the Destination Computer and click AddàKey. The Registry Details dialog appears.
Complete the fields on the Registry Details along as follows:
Operation: Create/update key and value
Root: HKEY_CURRENT_USER
Key: Software\Example
Value Name: Example
Data Value: [EXISTINGVALUE];newdata
Data Type: String
Click OK to close the Registry Details dialog.
Finally, add a condition to the component containing the registry value created above:
In the Components tab in Setup Editor, right-click on the component containing the registry key created above and select Details. The Component Details dialog appears.
Input NOT (EXISTINGVALUE~><”newdata”) in the Condition field. The “><” condition evaluates whether the value of the EXISTINGVALUE property contains “newdata”. The tilde (~) makes the comparison case-insensitive.
Click OK to close the Component Details dialog.
NOTE: Make sure the registry key created above is the only resource contained in the component modified above. Otherwise, other resources might not install if the condition evaluates as FALSE.
How will you determine the version of Windows Installer?
There are two ways to determine the version of Windows Installer:
- The installer sets the VersionMsi property to the version of Windows Installer run during installation.
- Right-click msi.dll in C:\WinNT\System32 and see Properties.
What applications should not be repackaged?
Do not attempt to repackage certain applications. Do not use Setup Capture to repackage the applications listed below:
- Pre-existing vendor MSIs.
- Operating Systems.
- Operating System Service Packs.
- Operating system hotfixes.
- Internet explorer
- Windows Media Player
- Windows Installer Service
- Norton Anti-virus.
Application Packaging Demo Video For Your Preview