First of all lets run the installer with a log:
msiexec.exe /i setup.msi /L*v log.txtIn the rather large log file we see:
MSI (s) (C8:6C) [16:20:10:162]: Invoking remote custom action. DLL: C:\Windows\Installer\MSIE4FD.tmp, Entrypoint: ManagedInstallThe error is slightly misleading. It is to do with a lack of administrator priveldges for the custom action. To fix this we need to set the NoImpersonate bit on the custom action. Unfortunatly vs2005 does not let you do this easily. To resolve this take the following steps:
MSI (s) (C8!EC) [16:20:13:747]: Note: 1: 2262 2: Error 3: -2147287038
MSI (c) (44:CC) [16:20:13:757]: Note: 1: 2262 2: Error 3: -2147287038
DEBUG: Error 2869: The dialog ErrorDialog has the error style bit set, but is not an error dialog
MSI (c) (44:CC) [16:20:13:803]: Font created. Charset: Req=0, Ret=0, Font: Req=MS Shell Dlg, Ret=MS Shell Dlg
The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2869. The arguments are: ErrorDialog, ,
MSI (c) (44:CC) [16:25:00:976]: Note: 1: 2262 2: Error 3: -2147287038
- Add the following code to a new file called NoImpersonate.js:
// Performs a post-build fixup of an msi to change all deferred custom actions to NoImpersonate
// Constant values from Windows Installer
var msiOpenDatabaseModeTransact = 1;
var msiViewModifyInsert = 1
var msiViewModifyUpdate = 2
var msiViewModifyAssign = 3
var msiViewModifyReplace = 4
var msiViewModifyDelete = 6
var msidbCustomActionTypeInScript = 0x00000400;
var msidbCustomActionTypeNoImpersonate = 0x00000800
if (WScript.Arguments.Length != 1)
WScript.StdErr.WriteLine(WScript.ScriptName + " file");
var filespec = WScript.Arguments(0);
var installer = WScript.CreateObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);
sql = "SELECT `Action`, `Type`, `Source`, `Target` FROM `CustomAction`";
view = database.OpenView(sql);
record = view.Fetch();
if (record.IntegerData(2) & msidbCustomActionTypeInScript)
record.IntegerData(2) = record.IntegerData(2) | msidbCustomActionTypeNoImpersonate;
record = view.Fetch();
- Add the file as an existing file to your setup project.
- Find the PostBuildEvent in the properties for your setup project.
- Set the PostBuildEvent to the following:
cscript.exe "$(ProjectDir)NoImpersonate.js" "$(BuiltOuputPath)"
- Rebuild. You're done!
Edit number 2: I had thought that there was a typo with the build output path shortcut. I thought the typo is a missing t, however you may want to double check this when adding it to your post build events. Originally it was copied from msdn (http://msdn.microsoft.com/en-us/library/ms165452.aspx) and if you use the macros button in the post-build event dialog in vs you still get $(BuiltOuputPath).