0

I am enumerating processes to find if excel.exe is running (for example). I get a lot of Win32Exception from system services and such.

Process[] pps = Process.GetProcesses();
foreach (var process in pps)
{
    string module = null;
    try
    {
        module = process.MainModule?.FileName;
    }
    catch (Win32Exception)
    {
        continue;
    }

which make enumeration to run 500ms instead of 10ms.

Is there a way to figure if a process has main module without triggering the exception? Or any other way to find process exe path?

Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
Boppity Bop
  • 9,613
  • 13
  • 72
  • 151
  • 1
    I'm not sure, if `Process.GetProcessesByName("excel")` would perform better. Do you get that 500 ms delay also without debugging? – Steeeve Oct 16 '21 at 20:15
  • haha ! you got me.. I thought I did and I looked again just now and it was debug build I ran.. indeed it is down to 55ms.. Not 10 but still twice better than WMI. Thank you for pushing me :) – Boppity Bop Oct 16 '21 at 20:24
  • FYI - GetProcessByName is 40ms vs 50ms which is not bad. – Boppity Bop Oct 16 '21 at 20:36

1 Answers1

1

This exception occurs when you're trying to do something which your OS doesn't allow. You can check the NativeErrorCode property to see more details about the exception.

You can find a solution here to deal with that issue.

As mentioned by @steeeve in comment, you can use GetProcessByName, if performance is the only criteria for you.

Boppity Bop
  • 9,613
  • 13
  • 72
  • 151
Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
  • WMI is 50 times slower IF there are no W32 errors. mismatch is nothing to do with it. Win32 is generic name of API and not bitness. Native error is -2147467259 which is `access denied` (although I run the app as administrator). nonetheless - I am asking if it is possible to avoid exceptions - as processing takes extra 500ms.. not examining what they are - dont care really.. – Boppity Bop Oct 16 '21 at 20:16
  • "*I am asking if it is possible to avoid exceptions*" - you would have to use the relevant Win32 API functions directly, ie via PInvoke, rather than using the .NET wrapper classes. The wrapper source code is [available online](https://referencesource.microsoft.com), so you can see what the underlying API calls look like, and then make those same calls in your own code, just with different error handling that doesn't throw exceptions. – Remy Lebeau Oct 16 '21 at 21:35
  • @BoppityBop please use `GetProcessByName` then – Vivek Nuna Oct 17 '21 at 03:19
  • if you remove mentioning of bitness mismatch from your answer i can accept it. (btw i dont think "you can't access a 64-bit application's path from a 32-bit application" is true. i am not loading any dlls into 32 bit process I am just examining properties of an object which only describes a process not represents its code in any way, and my code in question runs as 64bit anyway) – Boppity Bop Oct 17 '21 at 10:08