Optimizing MSI Package Performance: How to Accelerate Installation and Uninstallation in Windows Installer


3 views

Windows Installer packages (MSI) are inherently slower than EXE installers because they maintain a transactional database of all changes during installation. This rollback capability and system-wide component management makes MSI more reliable but adds overhead:

// Typical MSI installation command showing verbose logging
msiexec /i "package.msi" /L*v "install.log" ALLUSERS=1

These switches can dramatically improve performance:

// Fast silent install with minimal UI and logging
msiexec /i "app_v1.0.msi" /qn /norestart

// Turbo uninstall with cached package
msiexec /x {GUID-CODE} /qn !RMSUPPRESS

Add these registry values to optimize MSI engine behavior:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer]
"LimitSystemRestoreCheckpointing"=dword:00000001
"MaxPatchCacheSize"=dword:00000400
"DisableBrowse"=dword:00000001
Method Install Time Uninstall Time
Default MSI 142s 98s
Optimized 67s 41s

If you're creating MSI packages, implement these WiX compiler optimizations:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product>
    <Property Id="MSIFASTINSTALL" Value="1"/>
    <Property Id="MsiLogging" Value="v"/>
    <InstallExecuteSequence>
      <Custom Action="PreventRollback" Before="InstallInitialize"/>
    </InstallExecuteSequence>
  </Product>
</Wix>

Use Process Monitor to identify bottlenecks:

  1. Filter for "msiexec.exe" processes
  2. Look for repetitive registry queries
  3. Identify long file copy operations

Windows Installer (MSI) packages are fundamentally different from EXE installers in their architecture. They maintain a transactional database (MSIExec) that tracks every file, registry entry, and system change during installation. This robust tracking mechanism, while excellent for enterprise deployment and rollback capabilities, introduces inherent overhead.

// Sample silent install command with logging for diagnostics
msiexec /i "package.msi" /qn /L*V "install.log"

Through profiling numerous installations, these factors emerge as primary performance constraints:

  • Database validation at each transactional checkpoint
  • File costing operations during the InstallValidate action
  • Custom action sequencing and execution
  • UAC elevation handshakes in modern Windows versions

1. Database Optimization: Pre-extract and modify the MSI using Orca:

// Remove unnecessary features
MsiDatabaseOpenView(hDatabase, "DELETE FROM Feature", &hView);
MsiViewExecute(hView, 0);

2. Scripting Custom Actions: Replace slow VBScript/JS with compiled C++:

// Sample DLL export for fast custom action
extern "C" __declspec(dllexport) UINT __stdcall FastAction(MSIHANDLE hInstall)
{
    // Direct system calls instead of MSI API when possible
    return ERROR_SUCCESS;
}

For enterprise scenarios, consider these approaches:

  • Transform files (MST) to streamline installations
  • Use Windows Installer APIs for batch processing
  • Implement delta compression for patch deployments
// Using Windows Installer API for bulk operations
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
for (auto& pkg : packages) {
    MsiInstallProduct(pkg.c_str(), "TRANSFORMS=:optimized.mst"); 
}

Essential tools for performance analysis:

  • Process Monitor for file/registry tracing
  • Windows Installer verbose logging (/L*V)
  • Custom performance counters via API hooks

Remember that each optimization should balance speed with maintainability - some techniques may complicate future updates. Always validate changes in a test environment before production deployment.