3

What I'm trying to do is get the processing time per process using a method

//Current Method
public string GetRunningTime(Process p){
   string returnString = "00:00:00:00.00";//DD:HH;MM;SS.ff
   try{
      returnString = DateTime.Now.Subtract(p.StartTime).ToString(@"dd\.hh\:mm\:ss\.ff");//Time now - StartTime. ToString With format
   }catch(Exception){}//Catchs System.ComponentModel.Win32Exception: 'Access is denied'
   return returnString;//returns the string.
}

And the try-catch is the only way I could do the math without crashing. I was wondering if there is a way to know if the program has access to view the StartTime. so it would know not to do the math.

//Example Method
public string GetRunningTime(Process p){
   string returnString = "00:00:00:00.00";
   if(p.HasAcessToStartTime){//Trying to immitate
      returnString = DateTime.Now.Subtract(p.StartTime).ToString(@"dd\.hh\:mm\:ss\.ff");
   }
   return returnString;
}
Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
Anguish G
  • 43
  • 5
  • 1
    what exception are you getting, exactly? also: what's wrong with catching an _exceptional_ error? – Franz Gleichmann Sep 03 '20 at 15:44
  • Getting the `StartTime` shouldn't have anything to do with access of a user and or program. [Have](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.starttime?view=netcore-3.1#exceptions) you checked into the exceptions *it could throw*? On another note worth mentioning, that method could be marked as `static` as it doesn't do anything with a current state. – Trevor Sep 03 '20 at 15:51
  • The exception that it throws is "System.ComponentModel.Win32Exception: 'Access is denied'" – Anguish G Sep 03 '20 at 15:56
  • 1
    @AnguishG have you checked this: `32-bit processes cannot access the modules of a 64-bit process. If you try to get information about a 64-bit process from a 32-bit process, you will get a Win32Exception exception. A 64-bit process, on the other hand, can access the modules of a 32-bit process` [may be happening](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process?view=netcore-3.1)? – Trevor Sep 03 '20 at 15:59

2 Answers2

3

According to the official documentation, the StartTime shows you if something is wrong only via Exceptions.

NotSupportedException

You are attempting to access the StartTime property for a process that is running on a remote computer. This property is available only for processes that are running on the local computer.

InvalidOperationException

The process has exited.
OR
The process has not been started.

Win32Exception

An error occurred in the call to the Windows function.


There are a few options available to explain the problem:

  • Please, make sure that your executable is running as Administrator, because if not your program might be restricted to access some of the Processes.
  • As @Çöđěxěŕ correctly mentioned, check if you are trying to call 64-bit process from 32-bit.
  • Some processes (for example the svchost system process) as mentioned in this answer may behave that way.
Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
  • When I run the process as administrator it worked just fine. but what I'm trying to do is be able to run the program, not as an administrator and not use the try-catch. So is there a way to check if the program has permission to get the StartTime. – Anguish G Sep 03 '20 at 16:08
  • @AnguishG, unfortunately, there is no way to know if you can have access to the process other than catching the exception. However, you can try to check if the process is running as Administrator (check [here](https://stackoverflow.com/questions/1089046/in-net-c-test-if-process-has-administrative-privileges/1089061)). – Arsen Khachaturyan Sep 03 '20 at 16:13
0

There is no generalized means to check whether you can access process information, because each process can have a different discretionary access list. The appropriate means to check whether you can access the information is to attempt to access the information. Even if such a check did exist, it opens a TOCTOU error if the DACL is changed between check and access.

If your concern is regarding the "cost" of exception handling, then you should profile the application to verify that cost. In most cases, exception handling is not the real performance problem.

If you were for some reason running this code in a tight loop, and you really needed to avoid the cost of throwing exceptions, you can call GetProcessTimes directly, which would return zero in the event of an error. But if you are calling this in a tight loop, consider... not doing that. This seems like information that could be readily cached.

Mitch
  • 21,223
  • 6
  • 63
  • 86