0

We have an application written in both C++ and .NET that installs for all users in the Program Files folder. This application downloads new versions of itself (as MSI installers) and spawns the new installer process to replace itself.

The install process as it exists today:

  1. Copy an install manager app (C#, .NET 2.0) to the temp directory. Call this 'Manager'
  2. Manager is executed with elevated privs per this article.
  3. The original application exits.
  4. Manager spawns the MSI installer (with elevated privs, since the copy is elevated)
  5. Manager spawns the new version of the app.

The bug:

The newly installed app is running in an elevated state. This causes problems I won't enumerate here.

Ideally, the launch of the newly installed app would be run with the permissions of the original user.

I can't figure out how to demote the app back to being the standard user after elevation.

An inelegant hack:

(yeah, yeah, this whole process is inelegant anyway)

  1. Copy the install manager to the temp directory
  2. Run the install manager with standard user privs. Lets call this instance 'LowlyManager'.
  3. Original application exits.
  4. LowlyManager spawns the app again, this time with elevated privs. Let's name this instance 'UpperManagement'
  5. UpperManagement spawns the installer
  6. UpperManagement exits gracefully, returning the exit code of the installer.
  7. LowlyManager interprets the error code from UpperManagement, and spawns the newly installed application. This time as the original invoker.

Is there a better way to do this?

(I've left out a bunch of other details before and after these steps that make the process smoother for the user, but this should be enough to understand the core of the problem I'm trying to solve.)

Other requirements:

  • We can't install as a per-user app
  • The user shouldn't be presented with an authentication dialog box if UAC would have simply asked "are you sure you want to allow this?". I think this might kill a solution using WindowsImpersonationContext, but I'm not sure.
  • The system needs to work on XP, Vista, and Windows 7 (even if there is a separate process for XP).
Community
  • 1
  • 1
Brian Gillespie
  • 3,213
  • 5
  • 27
  • 37
  • 1
    How did you create the MSI? Why does your 'Manager' need to be elevated? Typically, Windows installer will handle elevation for you and you don't need to start your MSI with elevation. – Dirk Vollmar Apr 01 '10 at 00:05
  • "The user shouldn't be presented with an authentication dialog box": There is *no way* around getting user consent (unless UAC is disabled, of course). That's the whole point of UAC. – Dirk Vollmar Apr 01 '10 at 00:07
  • Re: "Typically, Windows installer will handle elevation..." We elevate prior to installation because we have a service running that needs to be stopped prior to installation. If we don't stop the service manually, then the Windows Installer Engine will gripe about the service (even though there is code in the MSI to stop the service prior to installation). Essentially we're trying to streamline the installation so user's aren't pestered with a bunch of needless dialogs. - Brian – Brian Gillespie Apr 01 '10 at 15:58
  • Re: "There is no way around getting user consent...": True... but... Vista and Win 7 ask for consent several ways. The one that happens for users with admin elevation permission is the "Do you want to let (app) make changes to your system." The response from the user is a simple yes/no answer. If you don't have elevation rights, you get a username/password dialog. As far as I can tell, using WindowsImpersonationContext requires explicit credentials, meaning I'd have to prompt for username/password even in cases where UAC would simply ask the "yes/no" question. This is not acceptable. – Brian Gillespie Apr 01 '10 at 16:02
  • I don't know what tool you are using for creating your MSI, but in WiX it seems possible (though I haven't tried it myself) to uninstall/close a running application after demanding elevation (see http://n2.nabble.com/Uninstall-can-t-stop-running-application-due-to-UAC-td3336684.html) – Dirk Vollmar Apr 01 '10 at 19:48
  • Re: "WiX..." I am using WiX, and it is possible, and it works great. But the Windows Installer Engine is so brilliant that it wans the user about the application being in use even though the installer will stop the service prior to replacing it. Again, it's a user experience streamlining that Microsoft didn't quite nail. – Brian Gillespie Apr 06 '10 at 17:13

1 Answers1

1

One way: http://www.codeproject.com/KB/vista-security/VistaElevator.aspx

Another way (mentioned in most recent comment in previous article): http://brandonlive.com/2008/04/27/getting-the-shell-to-run-an-application-for-you-part-2-how/

Kyle Alons
  • 6,955
  • 2
  • 33
  • 28