Click here to Skip to main content
11,411,840 members (64,295 online)
Click here to Skip to main content
Technical Blog

Bugs in System.Diagnostics.Process Class

, 20 Dec 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
Bugs in System.Diagnostics.Process Class

While working on an application which makes use of Process class, I found several bugs which occur in special conditions. More specifically accessing StartTime or HasExited properties causes a Win32Exception with NativeErrorCode equal to five. This indicates that the exception is caused by not having enough rights to retrieve the required information.

The exception occurs under the following conditions:

  • The source application should not be elevated
  • The process instance should represent an elevated process
  • The instance should not be a result of Process.Start call

The snippet below demonstrates these points:

//The following code will not throw an exception unless explorer is running elevated
var explorer = Process.GetProcessesByName("explorer").First();
Console.WriteLine(explorer.StartTime);
Console.WriteLine(explorer.HasExited);

var startInfo = new ProcessStartInfo("notepad") { Verb = "runas" };
var notepad = Process.Start(startInfo);

//Even though notepad is an elevated process no exception will be thrown
Console.WriteLine(notepad.StartTime);
Console.WriteLine(notepad.HasExited);

var notepad2 = Process.GetProcessById(notepad.Id);

//Exception is thrown.
try
{
    Console.WriteLine(notepad2.StartTime);
}
catch(Win32Exception e)
{
    Console.WriteLine(e.ToString());
}

try
{
    Console.WriteLine(notepad2.HasExited);
}
catch(Win32Exception e)
{
    Console.WriteLine(e.ToString());
}

By looking at the stacktrace we get when accessing StartTime property, we can see that Process.StartTime calls Process.GetProcessTimes which calls Process.GetProcessHandle which in turn calls ProcessManager.OpenProcess. This is where the exception is occurring. Using Reflector, we can see that ProcessManager.OpenProcess invokes native function OpenProcess and passes the desired access. In our case, the access that is passed is equal to 0×400 which corresponds to PROCESS_QUERY_INFORMATION access right. However, starting from Vista, there is a new access right called PROCESS_QUERY_LIMITED_INFORMATION which is enough for calling GetProcessTimes function. Let’s see what we get when calling GetProcessTimes with the new access right:

var startinfo = new ProcessStartInfo("notepad") { Verb = "runas" };
var process = Process.Start(startinfo);
var process2 = Process.GetProcessById(process.Id);

long create, exit, kernel, user;
var handle = NativeMethods.OpenProcess(0x1000, false, process2.Id);
NativeMethods.GetProcessTimes(handle, out create, out exit, out kernel, out user);
NativeMethods.CloseHandle(handle);
Console.WriteLine(DateTime.FromFileTime(create));

If you run this snippet, you will see that process start time is printed and no exception occurs. This solves the problem with StartTime property.

Printing the stacktrace of HasExited property shows that the exception occurs at exactly the same place. In this case, the requested access is 0×100400 which is a combination of PROCESS_QUERY_INFORMATION and SYNCHRONIZE. As you have probably guessed, it is again enough to use PROCESS_QUERY_LIMITED_INFORMATION instead of PROCESS_QUERY_INFORMATION. I will not show the full code here as it is quite straightforward.

So, if you receive access denied exception when querying StartTime or HasExited, make sure that the target process is not an elevated process. If it is, you will have to manually retrieve the information you need.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Giorgi Dalakishvili
Software Developer
Georgia Georgia
No Biography provided
Follow on   Google+

Comments and Discussions

 
QuestionBug? PinmemberJoel Lucsy20-Dec-11 4:09 
AnswerRe: Bug? PinmemberRobertCooley20-Dec-11 5:36 
GeneralRe: Bug? PinmemberJasper4C#21-Dec-11 2:30 
AnswerRe: Bug? PinmemberJohn Kasra15-Jan-12 12:03 

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.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150414.5 | Last Updated 20 Dec 2011
Article Copyright 2011 by Giorgi Dalakishvili
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid