views:

484

answers:

3

Hello!

Background: I am by no means a windows security / user permissions expert. I have an application (written in C#), that has to be able to write / delete files & folders in its root directory, write / delete files elsewhere on the disk, write/modify values in System Registry (Local Machine) and start & stop other applications and services. I figure that I need administrator privileges for at least some of those actions.

I tried running this and on computers with UAC turned off it works great without any additional settings. However on computers with UAC turned on (any level above 'never notify' in Windows 7) it will crash. I need it to work on all computers.

Up to now I would just manually check the "run this program as administrator" checkbox and everything would be fine. However now we have decided that we will allow customers to install this software on their own, and it needs to run "out of the box".

I have a deployment project in Visual Studio 2008 that installs everything and writes the necessary start up data in registry. What I need to do now is to set the "Run this program as Administrator" flag. I am guessing this isn't quite as simple as I'd like it to be.

So What is the proper way of doing this? This program is started on startup, and it would be irritating for our customers if UAC would pop up (and possibly dim the screen) every time they restart their computer.

Thank you for your help.

EDIT: Thank you for your replies. I realise that working around UAC would be frowned upon, and I can see that Microsoft does not support "white lists" so it would ask for permission only once. That's fine I can respect that, however I do have some follow up questions:

  • Can you provide me with a link that will show me how to properly elevate the program to correct elevated state? Is there any literature on what are the options, etc... Basicly I'd love a UAC 101 guide.

  • Is there a way to elevate the security status when I need the extra privileges (and only then prompt with UAC). Basicly this applications runs in the background, doing mostly nothing for most of the time. Every now and again it will check some files (at this point I will require to be able to write to disk and read the registry (read only is fine at this point), however since it's a temporary folder it wouldn't matter where I'd put it. If there is a location where the application can write without any privileges that would be perfect.)

    However at some point I will need to preform all the rest of the tasks (user needs to confirm this action anyway) so if UAC would prompt at this point that would be no problem. Is there a way to elevate it just at this point, and then return it to default permissions?

  • Will such a solution work with older versions of Windows, including Vista and Xp (and perhaps older?) What would it take to make it work?

+1  A: 

The proper way is to elevate when the program starts, with the UAC prompt (which you can set via the program's manifest) - attempting to be clever and bypass it is frowned upon.

Think about it - if you could install something which would elevate automatically without the UAC prompt ... what would be the point of UAC?

To add a UAC manifest to a program you simply add the manifest in a project and edit it. A sample manifest for UAC is here. If you want to elevate at the last possible moment then you need a spawn separate process - you cannot elevate an existing process. So separate that bit out and then start it using

Process.StartInfo.UseShellExecute = true;
Process.StartInfo.Verb = "runas";
blowdart
Yes I can see that. What I'd really like is to UAC prompt only once (the first time the program is ran? Possibly during or right after installation).
Rekreativc
Can you provide a link to a walkthrough about how to properly elevate the program? Thank you.
Rekreativc
But you're missing the point of UAC if you think it should be a once only prompt. It doesn't work like that, it's supposed to appear before each time the privileges are needed. That is the "proper" way to elevate. To do that simply right click in your project in VS2008 and add a manifest file, then edit the UAC option inside the manifest as appropriate.
blowdart
Please see the newest edit of the question.
Rekreativc
Edited with more information.
blowdart
Thank you. I just have one question left, then I will accept your answer. How do I run an elevated process on start up? At the moment I have an registry entry in LocalMachine\Software\microsoft\windows\currentversion\run, but after adding UAC manifest the program no longer starts at start up. How do I fix that?
Rekreativc
You don't. If you need a program to be elevated when the machine starts then you write a windows service and configure it as an appropriate machine account.
blowdart
A: 

You need to rethink how your application works. You're quite correct that it would be annoying to display an elevation prompt on login. So don't do it. On the other hand, you may well have tasks which you need to perform using administrative access.

So you have two choices:

  • Change your tasks so that they no longer require administrative elevation (e.g., write your files elsewhere).
  • Break your application into a Windows service component and a user interface component. The service component can run under an elevated account (hopefully the least-elevated account necessary to perform the tasks you need to do). The user interface component can talk to the service (via named pipes or similar) when necessary.
Craig Stuntz
A: 

You can split your program into two components:

  • a user application running without elevation
  • a Windows service that is responsible for the tasks that require elevation

Since you're using .NET, communication between the components is probably easiest done using WCF.

And as a side note: Programmatically modifying files under C:\Program Files is not considered good practice and might lead to a number of other problems. Windows has dedicated places for storing configuration settings and other program data.

0xA3