Click here to Skip to main content
Licence 
First Posted 24 May 2004
Views 174,982
Bookmarked 65 times

RunAs Class

By | 14 Feb 2005 | Article
Class that wraps CreateProcessWithLogonW as well as a simple control that makes use of the RunAs class.

Sample Image - RunAs.jpg

Introduction

There are three projects in this solution: RunAs, UseRunAsControl, and ProcessToStart. RunAs is the focus of this solution; it contains the class that wraps CreateProcessWithLogonW. UseRunAsControl defines and makes use of a simple control implementing the RunAs class and is meant to test and show its functionality. ProcessToStart is simply a form that shows the domain and username of the user whose syntax it is running under. This is merely there to start with the UseRunAsControl to demonstrate its functionality.

Demo

To see the solution in action, grab a second set of credentials (make some dummy ones on your local machine, perhaps). Run UseRunAsControl.exe and provide the credentials. Click on "Command..." and browse to ProcessToStart.exe. Click on "Run Command". Provided the credentials are correct, you will see a MessageBox containing the process ID of the new process. ProcessToStart will display the username that it is running as. If the credentials that UseRunAsControl.exe is running under has enough privileges, when you close ProcessToStart, you will see another MessageBox notifying you that the process has ended. If the user does not have privileges to the new process, you will see a MessageBox notifying you of this, and when ProcessToStart.exe exits, you will not receive any notice.

Class Usage

Using the RunAs class is simple. Add a reference to the assembly and include the namespace VastAbyss. There is an overloaded static method named StartProcess in the class. This simple overload provides standard functionality that starts the executable as the user and loads the profile. A word of caution with using this method is that if the command line is C:\Program Files\Some Directory\Some.exe, if a Program.exe exists in C:\, it will be started and this may be seen as a security flaw. It is due to the way that CreateProcessWithLogonW parses and searches the command line (space-delimited). To avoid this, surround the command line in quotes. All of the overloads return a Process. If the process failed to start, it will be null and a Win32Exception will be thrown. Below is a sample of the simple usage:

  string username = "SomeUser";
  string domain = "SomeDomain";
  string password = "I'll never tell!";
  string commandline = "\"C:\\Program Files\\Some Directory\\Some.exe\"";

  // Resulting string is
  //  "C:\Program Files\Some Directory\Some.exe"
  // with the quotes included.
  try
  {
    Process proc = RunAs.StartProcess(username, domain, password,
                                                    commandline);
    try
    {
      proc.EnableRaisingEvents = true;
      proc.Exited += new EventHandler(processExited);
    }
    catch
    {
      //The process started but you don't have access to it.
    }
  }
  catch (Win32Exception w32e)
  {
    // The process didn't start.
  }

To avoid the security risk of using command line, use one of the other overloads of StartProcess() to provide the executable in appname instead of command line (command line must be used to provide parameters to the executable if needed; i.e., c:\myapp.exe /q /t). These overloads provide many more options for creating the new process. Enums are provided for supplying the values of the flags. Additional overloads can easily be added to provide full control over creating the new process. The struct definition for StartUpInfo is public and can be used with the last overload to provide the maximum amount of control.

I have added a default constructor to the RunAs class. This constructor initializes the properties to the following values: UserName (System.Environment.UserName), Domain (System.Environment.UserDomainName), Password (empty string ""), ApplicationName (CurrentProcess.StartInfo.FileName), LogonFlagsInstance (LogonFlags.WithProfile), CommandLine (System.Environment.CommandLine), CreationFlagsInstance (CreationFlags.NewConsole), CurrentDirectory (System.Environment.CurrentDirectory), Environment (IntPtr.Zero), ProcessInfo (new ProcessInformation instance), StartupInfo (new StartUpInfo instance with the following values set: cb is set to the size of the new instance, dwFlags is set to StartUpInfoFlags.UseCountChars, dwYCountChars is set to 50, lpTitle is set to CurrentProcess.MainWindowTitle). After initialization, these values can be changed and the non-static method StartProcess can be called.

Control Usage

I will leave the below code included although the focus of this project is to implement the RunAs class and not this control. This control merely serves as an example of how the RunAs class can be used. I removed the RunAsControl from the RunAs project and placed it in the UseRunAsControl project.

The RunAsControl can be quickly added to a Windows Form and the four events wired up. That's all there is to it. Below is an example usage:

  RunAsControl m_runAsCtl = new RunAsControl();
  m_runAsCtl.ProcessStarted += new ProcessStartedEventHandler(m_pStarted);
  m_runAsCtl.ProcessFailed += new ProcessFailedEventHandler(m_pFailed);
  m_runAsCtl.ProcessEnded += new ProcessEndedEventHandler(m_pEnded);
  m_runAsCtl.ProcessAccessFailed += 
      new ProcessAccessFailedEventHandler(m_pAccessFailed);

Comment Disclaimer

I referred to the MSDN documentation for the CreateProcessWithLogonW, PROCESS_INFORMATION, STARTUPINFO, etc... functions, structs, and constants. Most of the comments in the source code are either direct quotes from this documentation or adaptations of information from that documentation.

Thanks

I would like to thank those who provided feedback to this project. I have incorporated the suggestions and fixed the bugs that I found. I hope that this makes the project better, but if there are still things that you think are wrong with it, I welcome more constructive criticism.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Dewey Vozel

Web Developer

United States United States

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralSpecific issue PinmemberSRoyalty5:05 10 Jan '11  
GeneralRe: Specific issue PinmemberDewey Vozel8:29 12 Jan '11  
GeneralLifesaver!!!! Pinmemberlemur6:55 14 Sep '10  
GeneralRe: Lifesaver!!!! PinmemberDewey Vozel1:53 16 Sep '10  
QuestionWhen press enter the app. runs Pinmembermelankolik660:38 10 Sep '09  
GeneralWait Extension PinmemberJoPa33:19 17 Aug '09  
QuestionRunAs error in XP sp2 PinmemberJake1234561:39 5 May '07  
AnswerRe: RunAs error in XP sp2 PinmemberJake1234562:23 5 May '07  
AnswerRe: RunAs error in XP sp2 PinmemberDewey Vozel7:54 5 May '07  
GeneralRe: RunAs error in XP sp2 PinmemberJake1234562:31 7 May '07  
GeneralRe: RunAs error in XP sp2 PinmemberNaresh N Jamadagni16:42 6 Nov '08  
Questioncan u runas user from other computer? Pinmembermikilior20:52 17 Jul '06  
QuestionCan I??? Pinmembertknman07008:10 19 Jun '06  
AnswerRe: Can I??? PinmemberDewey Vozel13:38 19 Jun '06  
GeneralRedirecting stdout, stderr, stdin PinmemberEyeHatePickingScreenNames7:40 27 Feb '06  
AnswerRe: Redirecting stdout, stderr, stdin PinmemberDewey Vozel13:20 28 Feb '06  
GeneralLicense PinmemberStefan Rusek3:19 11 Jan '06  
GeneralRe: License PinmemberDewey Vozel12:27 13 Jan '06  
GeneralStarting process from Windows Service Pinmembermrdance7:16 13 Jul '05  
AnswerRe: Starting process from Windows Service PinmemberEyeHatePickingScreenNames7:44 27 Feb '06  
QuestionRe: Starting process from Windows Service PinmemberKlampfi23:23 25 Apr '06  
EyeHatePickingScreenNames wrote:
I'm wanting to spawn processes from a Windows Service also. I found I needed to set the desktop member of StartInfo struct.

 
I've encountered another problem: my Windows Service starts a process which needs access to a network share. This process uses the correct username an domain but the networking rights got lost. If the process is started manually everything works fine.
Any ideas?
 
Thanks,
Martin
AnswerRe: Starting process from Windows Service Pinmemberdavelogie2:49 26 Apr '06  
GeneralRe: Starting process from Windows Service PinmemberKlampfi7:46 26 Apr '06  
AnswerRe: Starting process from Windows Service Pinmemberdavelogie8:41 26 Apr '06  
QuestionRe: Starting process from Windows Service PinmemberKlampfi3:36 27 Apr '06  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120529.1 | Last Updated 15 Feb 2005
Article Copyright 2004 by Dewey Vozel
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid