If "Process.HasExited" throws an exception, can I assume that the process has disappeared?

I have the following section of code designed to count the number of Excel processes currently in progress:

Func<int> OpenExcelProcessesCount = 
    () => System.Diagnostics.Process.GetProcessesByName("Excel")
              .Where(p => !p.HasExited)
              .Count();

Then I get the score at different points with the code, for example the following:

int excelAppCount = OpenExcelProcessesCount();

This code works 100% for several months. Then suddenly, today, he constantly gives me an exception, which reads as follows:

Exception: ApplicationThreadException

Message: Access is denied

Stack Trace:

   at System.Diagnostics.ProcessManager.OpenProcess(Int32

processId, Int32 access, Boolean throwIfExited)

   at System.Diagnostics.Process.GetProcessHandle(Int32

access, Boolean throwIfExited)

   at System.Diagnostics.Process.get_HasExited()

   etc...

, Process.HasExited ( System.Diagnostics.Process.get_HasExited() , ) . " " , , Excel , . .NET- .

, , System.Diagnostics.ProcessManager.OpenProcess(Int32 processId, Int32 access, Boolean throwIfExited). , "true" "throwIfExited". , , Process.HasExited try-catch , , HasExited "". ?

​​, , "Access is denied". - , , , , ?

, Stack Overflow, : hasExited throw 'System.ComponentModel.Win32Exception?. :

" runas, SYNCHRONIZE , PROCESS_QUERY_INFORMATION , GetExitCodeProcess , hasEnded Win32 ".

, , , . - , , , , , , - , . ( Excel, .)

...

Update:

, , . , , , "" . , .

, - . , ROT , / Excel, , "" . , , .

, , .

+5
4

, , . , , , , , HasExited , , .

: " , Excel, ". , . , Excel ? ( , - OLE Automation, .) GetProcessesByName , HasExited .

OpenExcelProcessesCount() , , GetProcessesByName ( "Excel" ). Excel, . , Excel, .

+4

Process.HasExited , , , - . StartTime.

: System.Diagnostics.Process Class

+6

:

.

, HasExited, .

+1

8 , .NET Process, . , , :) :

    hProcess = OpenProcess(ProcessAccessFlags.PROCESS_QUERY_LIMITED_INFORMATION, false, processId);

    GetExitCodeProcess(hProcess, out uint ExitCode);
    if (ExitCode != 259) // ExitCode of 259 is STILL_ACTIVE
    {
        CloseHandle(hProcess);
        return false;
    }

    // do your thing, this process is alive and you have a handle now

    CloseHandle(hProcess)

, :

    [DllImport("kernel32.dll")]
    static extern bool GetExitCodeProcess(IntPtr hProcess, out uint lpExitCode);

    [DllImport("kernel32.dll")]
    private static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, int dwProcessId);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool CloseHandle(IntPtr handle);

    [Flags]
    public enum ProcessAccessFlags : uint
    {
        PROCESS_QUERY_LIMITED_INFORMATION = 0x00001000,
    }
+1

All Articles