Link to home
Start Free TrialLog in
Avatar of dodgerfan
dodgerfanFlag for United States of America

asked on

Run a winforms application with elevated permissions

I have a winforms application (c#). It will be deployed to specific users' desktops. When it is run, I need it to run with elevated permissions. Specifically I want it to run with the permissions of an account I specify without having to enter the username and password. What is the best way to implement this? I'm working with visual studio 2017 in a Windows 8 environment.
Avatar of Chinmay Patel
Chinmay Patel
Flag of India image

Hi dodgerfan,

This technique is called user impersonation.
Here is a code sample

// The following example demonstrates the use of the WindowsIdentity class to impersonate a user.   
// This sample asks the user to enter a password on the console screen.   
// The password will be visible on the screen, because the console window   
// does not support masked input natively.  

using System;  
using System.Runtime.InteropServices;  
using System.Security;  
using System.Security.Principal;  
using Microsoft.Win32.SafeHandles;  

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

    public static void Main()  
        // Get the user token for the specified user, domain, and password using the   
        // unmanaged LogonUser method.   
        // The local machine name can be used for the domain name to impersonate a user on this machine.  
        Console.Write("Enter the name of the domain on which to log on: ");  
        string domainName = Console.ReadLine();  

        Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", domainName);  
        string userName = Console.ReadLine();  

        Console.Write("Enter the password for {0}: ", userName);  

        const int LOGON32_PROVIDER_DEFAULT = 0;  
        //This parameter causes LogonUser to create a primary token.   
        const int LOGON32_LOGON_INTERACTIVE = 2;  

        // Call LogonUser to obtain a handle to an access token.   
        SafeAccessTokenHandle safeAccessTokenHandle;  
        bool returnValue = LogonUser(userName, domainName, Console.ReadLine(),  
            out safeAccessTokenHandle);  

        if (false == returnValue)  
            int ret = Marshal.GetLastWin32Error();  
            Console.WriteLine("LogonUser failed with error code : {0}", ret);  
            throw new System.ComponentModel.Win32Exception(ret);  

        Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));  
        // Check the identity.  
        Console.WriteLine("Before impersonation: " + WindowsIdentity.GetCurrent().Name);  

        // Note: if you want to run as unimpersonated, pass  
        //       'SafeAccessTokenHandle.InvalidHandle' instead of variable 'safeAccessTokenHandle'  
            // User action  
            () =>  
                // Check the identity.  
                Console.WriteLine("During impersonation: " + WindowsIdentity.GetCurrent().Name);  

        // Check the identity again.  
        Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name);  

Open in new window

Please refer to the documentation for more details:

Specifically I want it to run with the permissions of an account I specify without having to enter the username and password.
You'd have to enter the credentials at some point, otherwise you'd not be able to log in as that account. Do you mean that you're going to embed the credentials into your code, as Chinmay has suggested above?
I think he meant to say manual entry of the credentials.

Please modify the sample above per your requirements. If I were to do it I'd store credentials in a config file and encrypt it using DPAPI.
Avatar of dodgerfan


Yes, I want to avoid having the user manually enter a username and password. I've using this example:
which I think comes from the one you put up here. I'm using it, and I've put in the click event of a button. The button is returns a list of files from a selected directory. I'm getting an error message that says: Could not find a part of the path. I'm usually selecting folders from mapped drives. Would that cause this issue? If it does, is there a fix?
Avatar of Chinmay Patel
Chinmay Patel
Flag of India image

Link to home
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Chinmay, I switched my code to use what you referenced first. I have it working now. But I got an error at first. "The user has not been granted the requested logon type at this computer". After some searching, I changed

Open in new window


Open in new window

I'm not sure I understand why that worked. I have not resolved my mapped drive issue yet, but after looking at it it feels like a sparate question. Thank you for your input. If I cannot get it resolved I open a  new question. In the meantime I'm going to close this one.
Whenever in doubt w.r.t. PInvoke, refer to:

You are to supply plain-text credentials for your scenario to work. It is strange, I wonder what kind of account you are using?
Please use the proper constants and their values from the

nst int LOGON32_LOGON_INTERACTIVE       = 2;
const int LOGON32_LOGON_NETWORK       = 3;
const int LOGON32_LOGON_BATCH         = 4;
const int LOGON32_LOGON_SERVICE       = 5;
const int LOGON32_LOGON_UNLOCK        = 7;

Open in new window