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>