Don’t Install from a Drive Substitution

If you’re not familiar with the subst.exe application, it allows you to create DOS devices for a given path using the DefineDosDevice API. Note in the API remarks the following:

Windows Server 2003 and Windows XP: The function creates a device name for a caller that is not running in the LocalSystem context in its own Local MS-DOS device namespace. If the caller is running in the LocalSystem context, the function creates the device name in the Global MS-DOS device namespace.

Because the Windows Installer service running as LocalSystem handles the deferred installation, on Windows XP and newer the system account will not have that drive substitution and your install will fail. Below is one such example.

MSI (s) (74:C8) [18:27:50:183]: Note: 1: 2203 2: X:Tools.msi 3: -2147287037
MSI (s) (74:C8) [18:27:50:199]: MainEngineThread is returning 3
MSI (c) (68:A4) [18:27:50:199]: Note: 1: 2755 2: 3 3: X:Tools.msi
DEBUG: Error 2755: Server returned unexpected error 3 attempting to install package X:Tools.msi.
The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2755. The arguments are: 3, X:Tools.msi,
MSI (c) (68:A4) [18:27:52:746]: Product: Tools — The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2755. The arguments are: 3, X:Tools.msi,
MSI (c) (68:A4) [18:27:52:746]: Back from server. Return value: 3

If you searched such a log for “value 3″ you’d find this block of text. Look above it for details. Notice the values in red. Windows Installer error 2203 (field 1) reads, “Database: [2]. Cannot open database file. System error [3].” Substitute fields 2 and 3 for the error tokens and you get the error message. -2147287037 in hexadecimal is 0x80030003, which is STG_E_PATHNOTFOUND. Finally, you can tell this is a server error because of the log line prefix that reads, “MSI (s)”, where the “s” means the action is running in the server context (plus the debug line reads that the server returned an unexpected error).