Introduction
This article shows a simple way to retrieve all managed processes information, like a .exe file, name, process ID, processes domains information, etc. The .NET class System.Diagnostics.Process that is used for operating system process manipulation or monitoring does not have a field, property or method indicating that the process is managed. The Process class gives programmers a powerful object model with large sets of properties, methods or events, but this class does not allow developers to retrieve domains loaded into the instance. To do this we will use the CLR infrastructure core debugging interfaces. This model is used by the Visual Studio debugger. For this article's purposes I will use ICorPublishProcess, ICorPublishProcessEnum, ICorPublish, ICorPublishAppDomain, ICorPublishAppDomainEnum interfaces and also the CorpubPublish class. They are defined as the CorPub.idl header, CorGuids.lib library, corpub.h C/C++ header and support all framework versions.
Background
To use these objects we must marshal them into valid .NET types. It's very easy, as we only must follow the same member order like the original COM declarations as in the example.
internal enum COR_PUB_ENUMPROCESS
{
COR_PUB_MANAGEDONLY = 0x00000001
}
[ComImport()]
[Guid("9613A0E7-5A68-11D3-8F84-00A0C9B4D50C")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ICorPublish
{
void EnumProcesses([In]COR_PUB_ENUMPROCESS Type,
[Out] out ICorPublishProcessEnum ppIenum);
void GetProcess([In] uint pid, [Out] out ICorPublishProcess ppProcess);
}
[ComImport()]
[Guid("A37FBD41-5A69-11d3-8F84-00A0C9B4D50C")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ICorPublishProcessEnum
{
void Skip([In] uint celt);
void Reset();
void Clone([Out] out ICorPublishEnum ppEnum);
void GetCount([Out]out uint pcelt);
int Next([In] uint celt, [Out] out ICorPublishProcess objects,
[Out] out uint pceltFetched);
}
[GuidAttribute("047a9a40-657e-11d3-8d5b-00104b35e7ef")]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComImportAttribute()]
internal class CorpubPublish { }
......
}
Using the Code
I've created a simple library called CorPublishLibrary that uses COM import declarations to retrieve local CLR running processes. The library contains only four classes:
ManagedProcessInfo - Represents local managed process instance.
MamagedProcessInfoCollection -Contains all current ManagedProcessInfo objects.
ManagedDomainInfo -It's a CLR running process domain info.
ManagedDomainInfoCollection -Contains all ManagedDomainInfo objects. The collections implement the ICollection interface.
To get MamagedProcessInfoCollection I've created the ManagedProcessInfo.GetProcesses() static method.
Also, the property of the ManagedProcessInfo class is called LoadedDomains which gets the MamagedProcessInfoCollection class instance. The ManagedProcessInfo instance can be converted to the System.Diagnostics.Process one by using the ConvertToDiagnosticsProcess() method.
Points of Interest
The current version of the library doesn't supress classic COM interfaces HRESULT method's return type. This may slow error handing. To prevent it, just add PreserveSigAttribute to these methods, but into cases like this you must check if every method's return value is different than null.