I have the following code section, designed to count how many Excel processes are currently open:
Func<int> OpenExcelProcessesCount =
() => System.Diagnostics.Process.GetProcessesByName("Excel")
.Where(p => !p.HasExited)
.Count();
And then later I retrieve the count at various points, with code such as the following:
int excelAppCount = OpenExcelProcessesCount();
This code has been running 100% fine for months. Then suddenly, today, it is consistently giving me an exception that reads the following:
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...
Basically, the call to Process.HasExited
(which shows up as System.Diagnostics.Process.get_HasExited()
in the stack trace, above) is failing. The error message "Access is denied" sounds like I don't have administrative privileges for the process, but the only Excel processes that exist would be created under my current user log-in, and the user can always access their own processes. My .NET code is also running under full trust.
The line that is ultimately failing is System.Diagnostics.ProcessManager.OpenProcess(Int32 processId, Int32 access, Boolean throwIfExited)
. I wonder if it is being passed in a value of 'true' for the 'throwIfExited' parameter. If this is the case, then I suppose that I could protect the call to Process.HasExited
with a try-catch block and assume that if this fails that HasExited
is, in fact, 'true'. But is this a safe assumption??
I am uneasy making a presumption like this, especially since the error message is "Access is denied." Does anyone have any ideas on how I might address this, or what I might test in an attempt to figure out what is going on?
The only similar thread I could find on Stack Overflow was the following: Why did hasExited throw ‘System.ComponentModel.Win32Exception’?. The answer given there was:
"Since you are doing runas, you only get SYNCHRONIZE access on the handle, not PROCESS_QUERY_INFORMATION access, hence GetExitCodeProcess fails, which results in hasEnded throwing a Win32 exception."
I don't really understand this answer and do not know if this applies in my case, but I thought I should mention it. If anyone feels that it is likely that this is the situation that I am facing, then if someone could try to clarify this answer for me, I would greatly appreciate it. (I'm an Excel programmer, I do not have much experience working with processes.)
Much thanks in advance...
Update:
Best I can tell, this is was a one-off corruption of some sort. The issues I faced started becoming increasingly bizarre as what had been a perfectly functioning set of unit tests was starting to have breakdowns at other "impossible" locations. A simple reboot corrected this issue and everything else I was facing.
My best guess is that I had some sort of bizarre corruption. Perhaps the ROT was corupted, and/or I had a hanging instance of Excel that was so corrupt that even 'Process' operations were not necessarily stable. Nothing conclusive, but this is all I can figure for now.
To the responders who took the time answer and help me out, I thank you.
Process.HasExited
can throw an access denied exception if the target process is running elevated and your process isn't. The same happens with StartTime
property, too.
I have written a blog post about this topic with a possible workaround: Bugs in System.Diagnostics.Process Class
The stack trace in the question also looks similar to the one that I have in the blog.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With