Jaa


Running Processes as a Different User

Before Whidbey, if you wanted to run code as a different user, you needed to use impersonation.  There was no easy solution for starting a new process and having it run with a different user's credentaials.  Probably the best solution in v1.0 and 1.1 of the framework was to P/Invoke out to CreateProcessWithLogonW, which required creating a P/Invoke signature and dealing with unmanaged interop.

The Process class in Whidbey provides a mechanism which allows you to specify the user context that the new process should run under.  This is exposed through three new properties on the ProcessStartInfo class, Domain, UserName, and Password.  UserName and Domain are exactly what you would expect, strings representing the user to log on, and the domain that the user is a member of.

Creating a process as a different user is also one of the first uses of the new SecureString feature, since the Password property is a SecureString.  In order for this to work, you need to make sure that you're not using ShellExecute by setting the UseShellExecute property of the ProcessStartInfo object to false.

Here's some sample code that acts as a very basic RunAs command.  The GetPassword function can be found in my posting about SecureString.

Console.Write("Username: ");
string user = Console.ReadLine();
string[] userParts = user.Split('\\');
        
Console.Write("Password: ");
SecureString password = GetPassword();

try
{
    ProcessStartInfo psi = new ProcessStartInfo(args[0]);
    psi.UseShellExecute = false;
            
    if(userParts.Length == 2)
    {
        psi.Domain = userParts[0];
        psi.UserName = userParts[1];
    }
    else
    {
        psi.UserName = userParts[0];
    }

    psi.Password = password;

    Process.Start(psi);
}
catch(Win32Exception e)
{
    Console.WriteLine("Error starting application");
    Console.WriteLine(e.Message);
}

Comments

  • Anonymous
    June 02, 2004
    great stuff!
  • Anonymous
    June 02, 2004
    Shawn has posted an interesting entry about how in Whidbey you can use the Process class to specify the user context that the new process should run under. This differs significantly from current approaches, as you normally have to P/Invoke CreateProcessWithLogonW to do it through impersonation. I've talked about different approaches before when I discussed spawning external processes securely in Windows and using restricted tokens to execute a process, but this is much more elegant. It's nice to see the Process class add new functionality through the exposure of three new properties on the ProcessStartInfo class: Domain, UserName, and Password. Here is a snippit that Shawn used (although of course you would do better input validation than that :) ): Console.Write("Username: ");string user = Console.ReadLine();string[] userParts = user.Split('');        Console.Write("Password: ");SecureString password = GetPassword();try{    ProcessStartInfo psi = new ProcessStartInfo(args[0]);    psi.UseShellExecute = false;                if(userParts.Length == 2)    {        psi.Domain = userParts[0];        psi.UserName = userParts[1];    }    else    {        psi.UserName = userParts[0];    }    psi.Password = password;    Process.Start(psi);}catch(Win32Exception e){    Console.WriteLine("Error starting application");    Console.WriteLine(e.Message);} Anyways, nice find Shawn!...
  • Anonymous
    June 02, 2004
    Shawn,

    That's some cool info - glad to see that is coming. As a matter of fact, I just got through writing some code today that calls to CreateProcessWithLogonW (and came accross your comment from a post on C# FAQ)! Weird how interconnected things become in the blogsphere.

    -Ryan
  • Anonymous
    June 04, 2004
    La versi
  • Anonymous
    July 30, 2004
    Yes, thank you for correcting (what I feel was) an obvious omission from the Process class.
  • Anonymous
    November 18, 2004
    Did you know that Process.Start always uses the security context of the parent ASP.NET process? I just found this out the hard way; Using Process.Start on "whoami.exe" always returns the ASPNET worker process no matter what I do. Some...
  • Anonymous
    March 09, 2006
    Valery
  • Anonymous
    March 09, 2006
    Nadja
  • Anonymous
    March 12, 2006
    Martin
  • Anonymous
    November 11, 2006
    hello, How I can run my batch file with parameters in c#?