Enumerating Process.GetProcesses() fails on Vista
It is hard to believe something as common as this could fail but it appears that enumerating System.Diagnostics.Process.GetProcesses() and calling a Process property fails on Vista. Here is the test demonstrating the issue:
[TestMethod]
[ExpectedException(typeof(System.ComponentModel.Win32Exception))]
public void EnumeratingGetProcessesThrowWin32Exception()
{
foreach(Process process in System.Diagnostics.Process.GetProcesses())
{
Console.WriteLine("{0}: ", process.ProcessName);
foreach (ProcessModule module in process.Modules)
{
Console.Write(" {0},", Path.GetFileName(module.FileName));
}
}
}
The message corresponding to the error is the ever helpful, "Access is denied" and it occurs regardless of whether you are running as an elevated process or not. The problem is caused by at least three processes when running elevated (as Administrator) or with UNC disabled: audiodg, System, and Idle. (audiodg process which is used as part of the digital rights management piece in Windows Vista.) Calling virtually an property on these three processes throws a Win32Exception.
To eliminate processes that throw exceptions on their properties from the GetProcesses() return using a where query operator (C# 3.0):
foreach (Process process in
System.Diagnostics.Process.GetProcesses().Where(
process =>
{
bool hasException = false;
try { IntPtr x = process.Handle; }
catch { hasException = true; }
return !hasException;
})
)
{
// ...
}
As part of investigating this I wondered what Sysinternal's Process Explorer did. It just shows the exception error message, "Access is denied."
UPDATE 2007-12-06:
Updated the where clause to filter by processes that threw exceptions and pointed out that Sysinternal's Process Explorer shows the properties for the processes with the exception message.
Tuesday, December 04, 2007 10:31:28 PM (Pacific Standard Time, UTC-08:00)