Mailbag: How to set the NoImpersonate flag for a custom action in Visual Studio 2005


Question:


I have built an installer using the Visual Studio 2005 setup project wizard.  It installs correctly on Windows XP but fails on Windows Vista.  I investigated and found that the failure on Windows Vista is caused by a custom action that fails with an access denied error.  However, I am running the setup with elevated privileges in Windows Vista.  How can I fix my setup so it will work correctly on Windows Vista?


Answer:


As Robert Flaming described in this blog post, it is necessary to set the NoImpersonate flag for custom actions that modify the system in Windows Vista.  This was an uninforced architectural intent that is now enforced in Windows Vista.


Unfortunately, there is not a way to directly set this flag for a custom action in the UI for the setup project in the Visual Studio IDE.  In Visual Studio 2005, you can use a post-build step that modifies the MSI to set this bit using a strategy previously described in this blog post.


You can use the following steps to set the NoImpersonate bit in a Visual Studio 2005 setup project:



  1. Download the sample script and extract the contents to the directory that contains the Visual Studio project you are working on

  2. Open the project in Visual Studio 2005
  3. Press F4 to display the Properties window
  4. Click on the name of your setup/deployment project in the Solution Explorer
  5. Click on the PostBuildEvent item in the Properties window to cause a button labeled “…” to appear
  6. Click on the “…” button to display the Post-build Event Command Line dialog
  7. Add the following command line in the Post-build event command line text box:
    cscript.exe “$(ProjectDir)CustomAction_NoImpersonate.js” “$(BuiltOuputPath)”
  8. Build your project in Visual Studio 2005

<update date=”1/22/2007″> Updated command line in step 7.  The variable I had specified previously was incorrect.  It actually needs to be spelled wrong using “ouput” instead of “output” in the $(BuiltOuputPath) variable </update>


<update date=”3/18/2009″> Fixed broken link to the sample script. </update>


 

Comments (69)

  1. Recently, I was helping a customer investigate an issue in an MSI-based installer that they created for

  2. A while back, I posted some instructions that can be used to run a post-build script to modify the custom

  3. If you have an installer for a Windows application that uses a custom action step during the installation process, you will likely hit this error message when trying to run that installer on Windows Vista: "The installer has encountered an unexpected

  4. There are a few Visual Studio 2005 bugs that surface when building installation packages on a Windows

  5. Question: I am using the Visual Studio 2005 web setup project wizard to create an MSI-based installer

  6. shajipd says:

    I have added the following command line in the Post-build event command line text box:

    cscript.exe "$(ProjectDir)CustomAction_NoImpersonate.js" "$(BuiltOuputPath)"

    When I build the MSI installer project it shows following error.

    Error 1 ‘PreBuildEvent’ failed with error code ‘1’ ‘Unspecified error’

    What s the solution for this ?

  7. Hi Shajipd – The steps listed in this blog post will run customaction_noimpersonate.js as a post-build step, but from your comments it sounds like a pre-build step is failing.  Do you have any other commands listed in the Visual Studio pre-build steps?  I would suggest starting by looking at those to try to narrow down this error further.

  8. Qasper says:

    Hi Aaron,

    I’ve tried to connect to the link to get CustomAction_noimpersonate.zip but the web page fails to be delivered… help please.

    Can you give an alternate site for this file?

    Thanks

    Q

  9. Hi Qasper – I’m sorry, but my file server appears that it is down for maintenance for the holiday weekend.  I don’t have an alternative download location.  If the site is not back up by the time I’m back at work on Tuesday, I will post the text of the script on my blog so you can copy and paste it and run it on your system.

    I’m sorry for the hassle that this has caused you.

  10. Jaydeep says:

    Hi,

    I am also trying to download the ZIP file  CustomAction_noimpersonate.zip and unable to do so. If possible can you paste the file on bloag at earliest or give more hints so that I can write such script myself….

    Thanks,

    Jaydeep

  11. I previously posted a set of steps that can be used to toggle the NoImpersonate bit for custom actions

  12. Hi Qasper and Jaydeep – It looks like my file server is back up, so the download link should work again.  Just in case, I also posted the source code for this script at http://blogs.msdn.com/astebner/archive/2007/05/28/2958062.aspx so you can copy and paste it into a file that you can use when you build your VS setup projects.

    Sorry for the hassle, and hope this helps….

  13. Ken Gabe says:

    Greetings, this is not only my first blog here (bare with me!) but the first in a series on creating

  14. As I mentioned last time , deferred custom actions are generally no impersonate. In this entry, I hope

  15. lfgarbi says:

    Hi Everybody, I followed the intructions given here, the msi built OK. but when I try to install the msi in MS Vista I’m still getting the same error for the custom actions. I run the msi as Administrator on Vista… thanks.. any ideas???

  16. claudirim says:

    Hi there, I got a problem to run the script no impersonate script, my PostBuildEvent is:

    cscript.exe "$(ProjectDir)CustomAction_NoImpersonate.js" "$(BuiltOutputPath)"

    but I get the following error in the output window when when the CustomAction_NoImpersonate.js is executed, and of course the installation fails to install on vista:

    C:Source CodeVS 2005ProjectsSetupProjCustomAction_NoImpersonate.js(24, 1) Microsoft JScript runtime error: Subscript out of range

    Any help would be greatly appreciated, Thanks

  17. Hi Claudirim – Please note the exact spelling of the command line listed in the blog post above.  The variable name needs to be $(BuiltOuputPath) with the word "ouput" misspelled.  Your comment lists it as "output" and that will not work correctly.  Hopefully that will correct this issue.  Please let me know how it goes for you.

  18. Hi Lfgarbi – Are you sure that you’re running into the same permission issue that is described in this blog post?  Also, are you sure that the custom action attributes for your MSI are now being set correctly?  Does the same MSI install correctly on OS’s other than Vista?  I’d suggest looking at the MSI in an MSI editor tool such as Orca and confirming that the custom action attributes are being set correctly for your custom action.  If you’re still not able to figure things out, I can try to help if you can zip and send me a copy of your MSI and a verbose log file from a failing installation.  You can send those to Aaron.Stebner (at) microsoft (dot) com.

  19. NEO_GINELLI says:

    I have built an installer using the Visual Studio setup project wizard.  I added my Windows Service and Windows Forms Application to a setup project with custom actions. In the After_Install event of the ProjectInstaller class in the Service application, I programmatically started the service and enabled service desktop interaction.

    It installs and uninstalls without any problems to Window 2000 and Windows XP. However, when I tried installing the application on Windows Vista, I encounter this problem:

    Error: 2869, Unexpected Error –

    I stumbled upon this article and it helped with clear that error.

    I now have this error to deal with: Access Denied while trying to write AlertService.InstallState and then the installation rolled back.

    How can I fix my setup so it will work correctly on Windows Vista?

  20. Hi NEO_GINELLI – If you are getting access denied while running a custom action in your MSI on Windows Vista, you will need to check the attributes of the custom action to make sure that it is marked as deferred and has the noImpersonate bit set so that it will run with the local system account privileges instead of the logged in user’s privileges.  The script listed above in this blog post can be used to mark custom actions in a VS setup project with the noImpersonate bit, which will hopefully fix this issue for you.  If that doesn’t work, you will need to debug your MSI further by checking the custom action attributes in an MSI viewing tool like Orca.exe.

  21. binujacob says:

    Hi Aaron

    The script works fine for my msi in Vista Business Edition but fails in Vista Home Premium. I get the error message "The installer has encountered an unexpected error installing the package.  This may indicate a problem with the package.  The error code is 2869."

    Can you help me with some workaround?

    Thanks

    Binu

  22. Hi Binujacob – This script does not do anything that is different between the editions of Windows Vista.  This error could indicate a problem within your custom action code (as opposed to a problem with the impersonation settings for your custom action).  I’d suggest trying to debug your custom action on the Home Premium system where it is failing to try to narrow this down.  You can use steps like the ones described at http://blogs.msdn.com/astebner/archive/2005/06/17/430320.aspx to set a breakpoint and attach a debugger to your custom action.

  23. binujacob says:

    Hi Aaron

    Thanks for your comments. You are right, the issue is not related to the impersonation setting. The issue is that when the database access fails from my Install() method, I throw a InstallException to rollback the installation. The funny thing is that eventhough I give a proper message while throwing the InstallException, it always shows the same "The installer has encountered an unexpected error installing the package.  This may indicate a problem with the package.  The error code is 2869.". I found a script similar to yours at http://blogs.msdn.com/nikhiln/archive/2007/04/25/post-build-script-to-fix-msi-issues-in-vista-for-vs-2005-setup-and-deployment-project.aspx but it doesn’t seem to be working. Can you suggest a solution for this issue?

    Thanks & Regards

    Binu Jacob

  24. Hi Binu – In this scenario, I don’t believe you have any control over the error code reported by Windows Installer.  The 2869 error is a generic error caused by any failure in this type of custom action.  I think your best bet in this scenario is to log the exception to the verbose MSI log file if your custom action ends up throwing so that a user will be able to find more detailed troubleshooting steps in the log file in this scenario.

  25. donce says:

    I found the solution and implemented it into my deployment project however it fails to rebuild the project and given error report " ‘PostBuildEvent’ failed with error code ‘1’ ‘Unspecified Error’

    i copy and paste this line

    cscript.exe "$(ProjectDir)CustomAction_NoImpersonate.js" "$(BuiltOuputPath)" so that i dont have any typo error. Any one have any idea how to solve this problem. I have already extract the file into the same folder as my solution file

  26. Hi Donce – You need to make sure that you copy the file CustomAction_NoImpersonate.js to your project’s root directory, and also make sure that you press enter to add a new line after any other post-build events that you might already have in your project.  If neither of these help, you may want to try to add message boxes to the JS file to narrow down exactly where it is failing.  Hopefully this helps.

  27. pshisbey says:

    Worked like a champ. Thank you Aaron.  I just needed a little clarity on exactly where to put the .js file.  Finally I put it in the deployment project’s folder (not added to the project but just in it’s folder) and presto!  Thanks again – phil.

  28. pandiarajan says:

    ..install.js(43, 1) Microsoft JScript runtime error: Subscript out of range. I got this while building the setup. In post build event cscript.exe "$(ProjectDir)install.js" "$(BuiltOutputPath)"

    I have changed the file name to install.js.

    The error must be at

    var filespec = WScript.Arguments(0);

    var installer = WScript.CreateObject("WindowsInstaller.Installer");

    var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);

    please help me.

    Regards,

    R. Pandiarajan.

  29. Hi Pandiarajan – The spelling of the post-build event that you listed is not correct.  The variable name needs to be $(BuiltOuputPath) – the word "ouput" is spelled wrong, but that is what Visual Studio expects it to be in this case.  Can you try fixing your post build event syntax to exactly match what is listed above in this blog post and see if that helps resolve this issue?

  30. sudev_gandhi@hotmail.com says:

    Hi There…

    I’ve set the NoImparsonate Flag to true using said script for my installer package. Still I’m facing the same error (code 2869) on Vista.

    After lot of efforts I came to know that when following code of my custom actions gets executed it shows the Error Code 2869, instead of showing the proper exception message as shown in other platforms (Windows XP for example)

    throw new InstallException("Database connection verification failed. Setup will exit now. Following exception has been occured: " + Environment.NewLine + ex.Message);

    Can anybody please guide me how to show proper message to user that particular database verification has been failed and then rollback the installation.

    Thanks in Advance

    Sudev Gandhi

  31. Hi Sudev_gandhi – A Windows Installer custom action does not get to decide what return code will get propagated to the end user when it fails.  That is up to Windows Installer itself and is based on several factors, such as the custom action type, the custom action scheduling options, etc.

    In this case, it is possible that the custom action is failing before it gets to the code to display the message that you are describing.  I’d suggest doing the following:

    1.  Verify in the MSI itself using a tool like Orca (from the Windows Installer SDK) that the custom action attributes are being updated correctly so it is marked with NoImpersonate so it will work with UAC on Vista.

    2.  If you have verified this, then you can use the MsiBreak variable to allow you to attach a debugger to your custom action process and debug this issue further.  You can use a technique similar to the one that I describe at http://blogs.msdn.com/astebner/archive/2005/06/17/430320.aspx to do this.

    Hopefully this helps.

  32. sudev_gandhi@hotmail.com says:

    Thanks Aaron,

    I verified the my MSI package with ORCA utility, and found no error. Later on I found the following…

    http://blogs.msdn.com/nikhiln/archive/2007/04/25/post-build-script-to-fix-msi-issues-in-vista-for-vs-2005-setup-and-deployment-project.aspx

    Which states that appart from impersonation on Vista UAC we have another issue with installer as follows.

    "The InstallException problem is a combination of the new architecture of Windows Installer 4.0 which is packaged with Visa and the ‘limited’-ness of VS 2005 while creating MSI. Windows Installer 4.0 expects an entry in th error table for all error codes. The InstallException class throws an error with the code 1001, but this error code is not present in the MSI’s error table due to which we get the ugly error! The funny part about this entire goof is that only Windows Installer 4.0 behaves like this with the previous version showing a proper error message to the user!"

    I made a dummy entry in Error table of the MSI Package for Error Code 1001 and Installer on Vista was on roll !!!

  33. lfgarbi says:

    Hi, I followed the 8 steps above and I’m still getting the same error. The error is hapening in a Windows Vista 64 bit machine. The package install OK in the others Windows versions.

    Thanks,

  34. Hi lfgarbi – If you are still getting an error during your installation, it is possible that there is some other problem with your custom action causing the install to fail.  You will need to troubleshoot/debug your custom action in order to narrow down why it is failing.  You can do this by using MSI verbose logging and/or by using custom action debugging techniques like the ones described at http://blogs.msdn.com/astebner/archive/2005/06/17/430320.aspx.

  35. lfgarbi says:

    I was able to use MSI verbose logging. These are the lines related with the custom actions.

    MSI (s) (64:B8) [13:52:42:797]: Executing op: CustomActionSchedule(Action=_11845818_114A_4BD8_82C6_7B65F3AABDE7.install,ActionType=3073,Source=BinaryData,Target=ManagedInstall,CustomActionData=/installtype=notransaction /action=install /LogFile= "C:Program Files (x86)QToolsSetupX64DatabaseSetup.exe" "C:UserslperezAppDataLocalTempCFG11EB.tmp")

    MSI (s) (64:34) [13:52:42:797]: Invoking remote custom action. DLL: C:WindowsInstallerMSICC8A.tmp, Entrypoint: ManagedInstall

    MSI (s) (64:FC) [13:52:42:797]: Generating random cookie.

    MSI (s) (64:FC) [13:52:42:797]: Created Custom Action Server with PID 3528 (0xDC8).

    MSI (s) (64:B0) [13:52:42:828]: Running as a service.

    MSI (s) (64:B0) [13:52:42:828]: Hello, I’m your 32bit Elevated custom action server.

    MSI (s) (64!38) [13:52:43:172]: Note: 1: 2262 2: Error 3: -2147287038

    MSI (c) (44:80) [13:52:43:172]: 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:80) [13:52:43:172]: 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:80) [13:54:14:898]: Note: 1: 2262 2: Error 3: -2147287038

    MSI (c) (44:80) [13:54:14:898]: Product: QToolsSetupX64 — 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, ,

    Error 1001.

    MSI (s) (64!38) [13:54:14:898]: Note: 1: 2262 2: Error 3: -2147287038

    MSI (s) (64!38) [13:54:14:898]:

  36. Hi Lfgarbi – This log shows that the custom action is being run elevated, so the changes that are made by the steps in this blog post are working as expected.  However, there is something within this custom action itself that are not working.  I’m not sure why that would be happening though.  You will need to try to debug your custom action (such as by using the MsiBreak instructions I sent a link to in my previous reply), or you may want to post a question on the VS setup/deployment project forum at http://forums.microsoft.com/msdn/ShowForum.aspx?ForumID=6&SiteID=1 to see if anyone there can suggest any additional debugging tips for this ManagedInstall custom action.

  37. lfgarbi says:

    Thanks a lot… I will follow your advice and try to debug the custom action.

    thanks…

  38. ronenfe says:

    Hi, i have a new program for windows mobile devices.

    The installer runs fine on windows xp.

    But in Vista I get the error described above.

    I followed the instructions but the error still the same.

    How can i know if the script runs ok?

    What can i do next?

    Thanks, Ronen.

  39. ronenfe says:

    Hi, i folowed the instructions, but i still get the same error.

    the installer is supposed to install a software for windows mobile devices , so after it finishes running it calls activesync to install the application to the mobile device.

    in xp it works ok , but vista gives 2869 error.

    how can i know if the script i downloaded from here did run ok? what else can i do?

  40. Hi Ronenfe – To start with, I’d suggest double-checking that running the script had the desired effect on your MSI.  To do that, you can install Orca from the Windows Installer SDK and look at the attributes in the custom action table of your MSI before and after running the script to verify that they have been changed as expected.

    Also, the script is only able to set the NoImpersonate bit for in-script custom actions.  If your ActiveSync custom action is not an in-script (also known as deferred)custom action, it will not be updated because Windows Installer doesn’t support setting the NoImpersonate bit unless the custom action is in-script (also known as deferred).  Typically, custom actions that run after an installation is complete are immediate custom actions and not deferred.

    For reference, you can find more information about Windows Installer custom action types and sequencing options in the MSDN topic at http://msdn.microsoft.com/library/aa368070.aspx.

  41. Cinni Patel says:

    Hi astebner,

    I am following the steps that you have described above

    Still getting the error

    ‘PostBuildEvent’ failed with error code ‘1’

    Let me be more specific

    1) Dev project named "TestApp"

    2) Setup project named "TestAppSetup"

    3) Copy "CustomAction_NoImpersonate.js" to TestApp

    4) "TestAppSetup" postbuild events add:

      cscript.exe "$(ProjectDir)CustomAction_NoImpersonate1.js" "$(BuiltOutputPath)"

    Still facing the error ‘PostBuildEvent’ failed with error code ‘1’

    Where i m doing wrong ? Can you please suggest me a way to get rid of the issue ?

  42. Hi Cinni Patel – The name of the variable needs to be $(BuiltOuputPath) instead of $(BuiltOutputPath).  The word Ouput is misspelled intentionally in the instructions in this blog post because that is what Visual Studio expects it to be named behind the scenes (this is a bug that was not fixed before VS 2005 shipped).  Also, you listed the name of your .js file as CustomAction_NoImpersonate1.js – I’m not sure if the 1 is a typo or if you renamed the file when you downloaded it, but I’d suggest double-checking that as well.

    Can you please try updating your post-build event command line and see if that helps?

    If that doesn’t help, then as a next step, I’d suggest looking at your build output to make sure that the $(ProjectDir) and $(BuiltOuputPath) variables are being resolved to the correct paths when the post-build step runs.  You might need to put the .js file in a different directory to get it to run correctly.

  43. yoyo1977 says:

    Hi,

    Thanks for your article.

    However, I have a problem. I want to run postbuild event with 2 conditions because i want to run script "CustomAction_NoImpersonate.js" if not terminalserver and an another script if terminalserver. Can you help me to do this ?

    Thank you very much.

    (Sorry for my english)

  44. Hi Yoyo1977 – I think what you’ll want to do for this scenario is create a new build configuration in Visual Studio, and assign different post-build steps to each of the build configurations.  That will allow you to run a different script depending on which configuration you are building.  You can find more information about VS build configurations in the MSDN topic at http://msdn.microsoft.com/library/kkz9kefa.aspx.

  45. yoyo1977 says:

    Hi astebner,

    No I don’t want to do this.

    I just want to assign a different postbuildevent in the property of the setup when i’m in the situation of Terminal Server.

    Example :

    cscript.exe "$(ProjectDir)CustomAction.js" "$(BuiltOuputPath)" for non terminal server

    cscript.exe "$(ProjectDir)CustomAction_Terminal.js" "$(BuiltOuputPath)" for terminal server.

    Thanks

  46. Hi Yoyo1977 – To do this, you will need to define an MSBuild property and set it to different values for the terminal server case and the non-terminal server case.  Then you can add a conditional statement to your post-build command that looks like this:

    if $(TerminalServer)==False cscript.exe "$(ProjectDir)CustomAction.js" "$(BuiltOuputPath)"

    if $(TerminalServer)==True cscript.exe "$(ProjectDir)CustomAction_Terminal.js" "$(BuiltOuputPath)"

    The trick for you will be to figure out how you figure out when to set the TerminalServer property to true or false.  I don’t know what you mean by "in the situation of Terminal Server" in your description, so you’ll have to set that based on what your scenario requires.

    Also, please note that I’m not an MSBuild syntax expert.  There are a lot of blogs and forum posts that you can find by doing a search for "Visual Stuido conditional post-build events" so you may want to review some of the other examples that are out there as you refine your syntax.

  47. Sasireka says:

    Hi astebner,

    I am following the steps that you have described above

    i need to install the setup in vista but i

    getting the below error

    The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2869

    how to check whether the javascript file working or not and how to find the path of "$(BuiltOuputPath)" and (ProjectDir)

    My postbuiltevent command is

    cscript.exe "$(ProjectDir)CustomAction_NoImpersonate.js" "$(BuiltOuputPath)"

    My development projectname is Test1 and setup project name is websetup1.where to put the js file. and how to check js file

  48. Hi Sasireka – You can look at the build output in Visual Studio to see the exact paths that $(ProjectDir) and $(BuiltOuputPath) get resolved to when your post-build command gets run.  You can use that information to make sure that you’re putting the .js file in the correct directory on your system.

  49. craig_aus says:

    Hi

    I’m using your script file referencing the post build event with the incorrectly spelt text.

    In my custom action (an C# EXE), I display a dialog with a text box:

    textbox.Text = Environment.UserName;

    However when I run the MSI, the textbox.Text value is "SYSTEM"

    Is there something wrong with the script, I was expecting the value to be my <WindowsAccountName>

    Craig

  50. Hi Craig_aus – No, there’s nothing wrong with the script – that is exactly what I would expect to see.  Setting the NoImpersonate custom action attribute means that it will not use impersonation.  That means that it will run with the same credentials as Windows Installer runs under (which is the local SYSTEM account).

  51. sowji250 says:

    Hi Aaron,

    I am facing the same issue "error code 2869" when installing my service on vista.

    I am not able to download the zip file "CustomAction_NoImpersonate.zip" from the "sample script(http://astebner.sts.winisp.net/Tools/CustomAction_NoImpersonate.zip)" link that you have given in this post.

    Can you please fix this issue so that I can download the file and implement your steps?

    Or else you can also email that file to me at sowji250@gmail.com.

    Really appreciate your help on this.

    Thanks & Regards,

    Sowjanya V

  52. Hi Sowji250 – My old WinISP file server was retired a few weeks ago, and I’ve been fixing up broken links as I find them.  I just updated this blog post with the new location of this sample script.  You can download it from http://cid-27e6a35d1a492af7.skydrive.live.com/self.aspx/Blog%7C_Tools/CustomAction%7C_NoImpersonate.zip.

  53. aufgang says:

    Hi, This posting is great.  Thank you so much for making this available.  

    I got your script working in JS, but have tried porting it to C# so that I can get it to run as part of some other code already running as part of a post-processing operation on an automated build process.  (I’ve actually modified it a bit as well, to UNSET the NoImpersonate bit and SET TSAware.)

    My C# code looks like this:

    public static void EditMSIDatabase(string msiFile)

    {

    Installer installer = (Installer)Activator.CreateInstance(

                                    Type.GetTypeFromProgID("WindowsInstaller.Installer")

                                    );

    Database database = installer.OpenDatabase(msiFile, MsiOpenDatabaseMode.msiOpenDatabaseModeDirect);

    string sql = "SELECT `Action`, `Type`, `Source`, `Target` FROM `CustomAction`";

    View view = database.OpenView(sql);

    view.Execute(null);

    Record record = view.Fetch();

    while (record != null)

    {

    if ((record.get_IntegerData(2) & (int)ExecutionContext.InScript) > 0)

    {

    int initalValue = record.get_IntegerData(2);

    record.set_IntegerData(2, record.get_IntegerData(2) & ~(int) ExecutionContext.NoImpersonate);

    record.set_IntegerData(2, record.get_IntegerData(2) | (int) ExecutionContext.TSAware);

    view.Modify(MsiViewModify.msiViewModifyReplace, record);

    }

    record = view.Fetch();

    }

    view.Close();

    database.Commit();

    }

    public enum ExecutionContext

    {

    InScript = 0x00000400,

    Rollback = 0x00000100,

    Commit = 0x00000200,

    NoImpersonate = 0x00000800,

    TSAware = 0x00008000,

    };

    When I run the code, it gets as far as the call to view.Modify, and then throws an exception.

    Unhandled Exception: System.ApplicationException: A COM exception was thrown while trying to write to the MSI file —> System.Runtime.InteropServices.COMExcept

    ion (0x80004005): Modify,Mode,Record

      at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)

      at WindowsInstaller.View.Modify(MsiViewModify Mode, Record Record)

      at AgileBuildPostProcessor.MSIFixer.EditMSIDatabase(String msiFile) in C:ProjectsAileBuildPostProcessorAileBuildPostProcessorMSIFixer.cs:line 36

    Any ideas what might be causing this and how to work around it?  Any help would be appreciated.

  54. Hi Aufgang – I don’t see anything that jumps out at me in looking at your code.  You may want to look at some of the samples in the Windows Installer SDK as a starting point

    There is also a managed code wrapper for the MSI APIs in WiX v3.0 (http://wix.sourceforge.net) that I’d suggest taking a look at.  It is called the Deployment Tools Foundation (DTF) and there is a good help file that comes with it as well.  To look at that, you just need to install one of the builds of WiX v3.0 from http://wix.sourceforge.net/releases/.

  55. lovecreatesbeauty@hotmail.com says:

    Hi, I apply your suggestion and re-built my msi in vstudio 2008. The msi still doesn’t work on vista and throws the same error:

    "There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor."

    Other reason causes this error?

  56. Hi Lovecreatesbeauty@hotmail.com – This error essentially means that the custom action is failing, but doesn’t provide any details about the root cause.  There could be a lot of possible causes for this type of error, depending on what your custom action is designed to do.  You will probably need to try to debug your custom action in more detail to narrow this down further.  You can do this by adding logging to your custom action or adding a dialog box at the beginning of your custom action so you can attach a debugger.  You could also try using the MsiBreak environment variable (described at http://msdn.microsoft.com/library/aa368264.aspx).

  57. Duncan Hornby says:

    Hi Aaron,

    Can I confirm something? I have built a .Net extension for some software called ArcGIS. I built an installer and everything worked fine on XP systems. Someone tried to install it on a Windows 7 system and got the error message. So I am looking at your blog as a solution. What I want to know is if I implement the above does that mean the installer will only work on Vista/Window 7 OS or will it still work on XP systems too?

    Duncan

  58. Hi Duncan Hornby – Changing the NoImpersonate flag will not cause any problems on Windows XP.  If that setting is what is causing the problem on Windows 7, then making the change listed in this blog post should allow the MSI to install on any OS.  Please note that you should try to confirm that this really is the root cause of the install failure before trying to make this type of change though.  You can do that by looking at the verbose MSI log file from a failing installation and searching for the string "return value 3".

  59. Santosh says:

    Hi Aaron

    When I build the MSI installer project it shows following error.

    Error 1 'PreBuildEvent' failed with error code '1' 'Unspecified error'.

    Cause of error : Can not find script file "E:delAdobeVS2005AdobeSerivceDeletePDFCustomAction_NoImpersonate.js".

    I am running 2 projects at the time of installation.

    Thanks in advance

    Santosh Patil.

  60. Hi Santosh – You're going to want to run this script as a post-build step, not a pre-build step.  The script updates the MSI that is produced by the build process, so running it as a pre-build step will not work because the MSI won't be built yet.  I'd suggest making sure that you're following the exact steps listed in this blog post so that it will run the script as a post-build step.  Also, the error message lists the full path where it expects to find the script, so I'd suggest double-checking that the script is saved at that exact path on your computer.

  61. Andy P says:

    Just to confirm that having read the thread all the way through I included the js file into my deployment folder and it all worked first time.  Many thanks all for this thread.  Its a serious time-saver!  A

  62. Naga says:

    Hello Aaron,

    How do I check if the noimpersonate is set correctly in the MSI. I followed your steps and rebuilt the solution and the build succeeded. Now when the client installs the msi, will they see this .js file copied down anywhere in their system?

  63. Hi Naga – No, the .js file will not be copied to the user's system.  It is only used at build time to make some modifications to the .msi file.  To verify the changes in the .msi, you would need to look in the .msi file after running the .js file on it.  Specifically, the settings for the Type column of the CustomAction table will be changed.  You can use the Orca tool in the Windows SDK (msdn.microsoft.com/…/aa370557.aspx) to view the tables in a .msi file.

  64. Naga says:

    Thanks for your quick reply Aaron. Unfortunatly, this solution is not resolving the issue I have. My msi still errors out with 2869. This error very recentand all was well until occur some Microsoft security patches for XP SP3 was installed( We are yet to determine which security patch as a number of them have been installed.)

  65. Hi Naga – If you've updated your MSI and it is still failing, it is possible that the issue described in this blog post is not the root cause of the failure.  Also, the issue related to teh NoImpersonate flag only affects Windows Vista and higher, and should not be an issue on Windows XP.

    I'd suggest looking in the verbose MSI log to see if there is any useful error information to help narrow down the root cause further.  You can use steps like the ones listed at blogs.msdn.com/…/help-me-help-you-if-you-have-setup-bugs.aspx to gather a verbose MSI log file from your installer.