-1

I want to run application usually with normal rights but for some operations(Managing file associations for example) request admin rights.

Is it possible?

P.S. I know about manifest and requestedExecutionLevel but this is not a good solution. I want aplication have admin rights for some period of time not always.

Ruslan F.
  • 5,498
  • 3
  • 23
  • 42
  • how about doing it with an event and when it is occured check for admin right (like it is mentioned in this post: http://stackoverflow.com/questions/1089046/in-net-c-test-if-user-is-an-administrative-user) , else the operation is not possible – patdhlk Sep 22 '14 at 08:29
  • @Ruslan Your accepted answer is absolutely the wrong way to solve this problem. The right way is described in detail in many places on MSDN. – David Heffernan Sep 29 '14 at 12:27

2 Answers2

1

That is not possible unless you start a new process.

You can do that with:

var psi = new ProcessStartInfo();
psi.FileName = @"yourExe";
psi.Verb = "runas";

Process.Start(psi);

You could start the same application as you are currently running and pass a switch parameter so the problem knows it only has to execute a specific action.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • Yes, if you'll give me a moment, I'll provide a full answer. In short though, you can use impersonation and the [`WindowsImpersonationContext` Class](http://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext(v=vs.110).aspx) to achieve these requirements. – Sheridan Sep 22 '14 at 09:42
  • 1
    +1 Down vote removed. I'll delete these comments too shortly. – Sheridan Sep 22 '14 at 09:58
  • @Patrick FWIW your original answer was accurate. It would be better if you reverted to revision 1. – David Heffernan Oct 03 '14 at 18:18
  • @David: I guess you have done extensive testing on this. Will revert the answer. Thanks for the heads up. Will test if I have some time myself. – Patrick Hofman Oct 03 '14 at 18:42
  • Well, I've done plenty of testing on Sheridan's code. But the documentation for UAC could hardly be any clearer. I think Sheridan was just a little confused. And Ruslan perhaps accepted and then moved on, without actually trying to implement anything. That does happen. – David Heffernan Oct 03 '14 at 18:48
1

You can use impersonation and the WindowsImpersonationContext Class to achieve your requirements. The idea is that the application runs with normal permissions, but when you need to access something that has higher permissions, the application can provide the log in details of a user account that has the correct permissions. It would look something like this:

using (ImpersonationManager impersonationManager = new ImpersonationManager())
{
    impersonationManager.Impersonate(Settings.Default.MediaAccessDomain, 
        Settings.Default.MediaAccessUserName, Settings.Default.MediaAccessPassword);
    // Perform restricted action as other user with higher permissions here
}

Note that this ImpersonationManager class is a custom class, so you won't find it on MSDN, but it just uses the SafeTokenHandle and other code from the linked page:

private SafeTokenHandle safeTokenHandle;
private WindowsImpersonationContext impersonationContext;

const int LOGON32_LOGON_NEW_CREDENTIALS = 9;

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

public void Impersonate(string domain, string username, string password)
{
    var isLoggedOn = LogonUser(username, domain, password, LOGON32_LOGON_NEW_CREDENTIALS, 0, out safeTokenHandle);
    if (!isLoggedOn)
    {
        var errorCode = Marshal.GetLastWin32Error();
        throw new ApplicationException(string.Format("Could not impersonate the elevated user. The LogonUser method returned error code {0}.", errorCode));
    }
    impersonationContext = WindowsIdentity.Impersonate(this.safeTokenHandle.DangerousGetHandle());
}
Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • If this works, and I find it hard to believe that it will, it sucks really hard. Where are you going to get the username and password from?! The correct way to do this is via another process. Either by simply starting a new process using the `runas` verb and `ShellExecuteEx`. `Process.Start()` with `UseShellExecute` under .net. Or by using the COM UAC elevation moniker. – David Heffernan Sep 29 '14 at 12:24
  • It works perfectly well, thanks... what would make you think that it wouldn't work? It's pretty simple code really. The password and username are simply stored in a Settings file. I've never had any problems, but if I do, I'll come back and try out your suggestion. – Sheridan Sep 29 '14 at 13:03
  • You store username and password in cleartext in a settings file? Is that a good idea? What happens when the user changes password? And which user's details do you store? Would have to be a user that was not subject to UAC I guess. Like Administrator. – David Heffernan Sep 29 '14 at 14:35
  • -1 This simply does not do as you describe. You need a new process, just as every MSDN article on UAC explains. – David Heffernan Sep 29 '14 at 14:58
  • @DavidHefferman, you are *so* incorrect. This `ImpersonationManager` impersonates a single user (set up specifically) that has been given access rights to some read only folders. The username and password values do not change as they are for a single user account. Not only does this work without using a new process, but it has been working without error for around 2 years now. It enables the application to save to read only folders that the current application user does *not* have access to. I suggest it's time for you to get your high horse before you start running your mouth off again. – Sheridan Sep 29 '14 at 16:20
  • It doesn't work. The question is about uac. When I run your code I still have standard user rights. No elevation. How could I elevate without a uac dialog. I suggest that you read the question. – David Heffernan Sep 29 '14 at 20:15
  • Also, unless you use @myname then I won't get notified of your comment – David Heffernan Sep 29 '14 at 20:22
  • One thing you might try is to request the current user name after you have started impersonating. Because you chose to use `LOGON32_LOGON_NEW_CREDENTIALS` you'll find that the user name returned is always the user that started the process. Irrespective of the user name that you passed to `LogonUser`. Did you mean to use `LOGON32_LOGON_INTERACTIVE` or `LOGON32_LOGON_BATCH` perhaps. But in any case, I see no evidence at all of elevation being performed. I think you need to reconsider this. Remember that the question wants to find a way to elevate. That which is done via one of the UAC dialogs. – David Heffernan Sep 29 '14 at 20:37
  • I've done quite a bit of testing now. It's true that this code can impersonate a different user. However, not if you use `LOGON32_LOGON_NEW_CREDENTIALS`. But `LOGON32_LOGON_INTERACTIVE` or `LOGON32_LOGON_BATCH` will give you a token for a different user. And if that user has rights that the original user has then fine. But in the question, we are talking about UAC and split tokens. `LogonUser` has no way to get you from the restricted token to the full token. You do need UAC elevation for that. As I said, that's either another process, or COM with UAC elevation moniker. As documented. – David Heffernan Sep 29 '14 at 20:46
  • @DavidHefferman, I really have no idea why you have such a bee in your bonnet about this answer. Not only does it work for me, but it also works for the other answer author *and* the question author. Also, suggesting that I *read the question* seems rather strange when the question author has already accepted my answer as the correct answer to their question. I suggest you find another crusade because no one is listening to your rant over here. – Sheridan Sep 30 '14 at 08:11
  • *unless you use @myname then I won't get notified of your comment*... what... you mean like I did in the comment *before* you wrote this 'tip'?? I suggest you read the comments and check if the user you're 'helping' needs your help before making such a ridiculous comment. Hopefully this can be an end to all this nonsense now. – Sheridan Sep 30 '14 at 08:12
  • That's not my name though. It was spelled incorrectly. No @ in the first comment. I've not been notified at all. – David Heffernan Sep 30 '14 at 22:08
  • These comments are for the benefit of future readers. I note that you seem to be evading the point. To be clear, are you claiming that the code in your answer allows a process that, under UAC, is started with a restricted admin token, to assume a full admin token? What's more, are you claiming that the code in the answer allows a process to impersonate a user other than the one that started the process? – David Heffernan Sep 30 '14 at 22:10
  • @DavidHeffernan, if you think that anyone is going to read through all of these comments, I'd say that you were deluded. I really can't understand why you are so obsessed with this situation. Perhaps the words in either the question or the answer could have been picked better, but at the end of the day, someone had a specific problem and I offered them a solution which they tried and accepted. Get on with your life and stop wasting my time. No one here cares about the point that you're trying to make as it is *clearly* not relevant to this post. – Sheridan Oct 01 '14 at 11:49
  • You didn't answer my questions. I take it that means the answers to both are in the negative. – David Heffernan Oct 01 '14 at 12:31