枚举所有没有mscoree的AppDomain

如何在不引用mscoree情况下枚举所有进程的域。 可能吗? 我从互联网上的某个地方找到了2007年的解决方案。 但它列举并清空收集。

这是代码:

 public static class DomainHelper { public static AppDomain[] LoadedDomains { get { var loadedDomains = new List(); var runtimeHost = new CorRuntimeHost() as ICorRuntimeHost; try { var enumeration = IntPtr.Zero; runtimeHost.EnumDomains(out enumeration); try { object nextDomain = null; runtimeHost.NextDomain(enumeration, ref nextDomain); while (nextDomain != null) { loadedDomains.Add((AppDomain) nextDomain); nextDomain = null; runtimeHost.NextDomain(enumeration, ref nextDomain); } } finally { runtimeHost.CloseEnum(enumeration); } } finally { Marshal.ReleaseComObject(runtimeHost); } return loadedDomains.ToArray(); } } [ComImport] [Guid("CB2F6723-AB3A-11d2-9C40-00C04FA30A3E")] private class CorRuntimeHost // : ICorRuntimeHost {} [Guid("CB2F6722-AB3A-11D2-9C40-00C04FA30A3E")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface ICorRuntimeHost { void CloseEnum(IntPtr enumHandle); void CreateDomain(); void CreateDomainEx(); void CreateDomainSetup(); void CreateEvidence(); void CreateLogicalThreadState(); void CurrentDomain(); void DeleteLogicalThreadState(); void EnumDomains(out IntPtr enumHandle); void GetConfiguration(); void GetDefaultDomain(); void LocksHeldByLogicalThread(); void MapFile(); void NextDomain(IntPtr enumHandle, [MarshalAs(UnmanagedType.IUnknown)] ref object appDomain); void Start(); void Stop(); void SwitchInLogicalThreadState(); void SwitchOutLogicalThreadState(); void UnloadDomain(); } } 

没有引用mscoree.tlb会让你遇到麻烦,ICorRuntimeHost声明错误。 方法顺序完全混淆,不清楚是怎么回事。 2007年,生活也变得更加简单,主机界面针对.NET 4.0进行了彻底重新设计,并且不推荐使用ICorRuntimeHost。 它仍然有效,肯定会有一段时间。

我将发布在.NET 4.0及更高版本上运行的代码。 正确的方法是从ICLRMetaHost开始。 然后获取您感兴趣的运行时实例的ICLRRuntimeInfo实例。请记住,.NET 4.0支持CLR的进程内并行实例化,您将希望找到您的代码正在使用的实例。 然后,ICLRRuntimeInfo :: GetInterface()方法可以将实例返回到传统的ICorRuntimeHost接口。

 using System; using System.Collections.Generic; using System.Runtime.InteropServices; public static class CLRUtil { public static IEnumerable<_appdomain> EnumAppDomains() { // Obtain ICLRMetaHost interface object objHost; int hr = CLRCreateInstance(ref CLSID_CLRMetaHost, ref IID_CLRMetaHost, out objHost); if (hr < 0) throw new COMException("Cannot create meta host", hr); var host = (ICLRMetaHost)objHost; // Obtain ICLRRuntimeInfo interface var vers = Environment.Version; var versString = string.Format("v{0}.{1}.{2}", vers.Major, vers.Minor, vers.Build); var objRuntime = host.GetRuntime(versString, ref IID_CLRRuntimeInfo); var runtime = (ICLRRuntimeInfo)objRuntime; bool started; uint flags; runtime.IsStarted(out started, out flags); if (!started) throw new COMException("CLR not started??"); // Obtain legacy ICorRuntimeHost interface and iterate appdomains var V2Host = (ICorRuntimeHost)runtime.GetInterface(ref CLSID_CorRuntimeHost, ref IID_CorRuntimeHost); IntPtr hDomainEnum; V2Host.EnumDomains(out hDomainEnum); for (;;) { _AppDomain domain = null; V2Host.NextDomain(hDomainEnum, out domain); if (domain == null) break; yield return domain; } V2Host.CloseEnum(hDomainEnum); } private static Guid CLSID_CLRMetaHost = new Guid(0x9280188d, 0xe8e, 0x4867, 0xb3, 0xc, 0x7f, 0xa8, 0x38, 0x84, 0xe8, 0xde); private static Guid IID_CLRMetaHost = new Guid(0xD332DB9E, 0xB9B3, 0x4125, 0x82, 0x07, 0xA1, 0x48, 0x84, 0xF5, 0x32, 0x16); private static Guid IID_CLRRuntimeInfo = new Guid(0xBD39D1D2, 0xBA2F, 0x486a, 0x89, 0xB0, 0xB4, 0xB0, 0xCB, 0x46, 0x68, 0x91); private static Guid CLSID_CorRuntimeHost = new Guid(0xcb2f6723, 0xab3a, 0x11d2, 0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e); private static Guid IID_CorRuntimeHost = new Guid(0xcb2f6722, 0xab3a, 0x11d2, 0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e); [DllImport("mscoree.dll")] private static extern int CLRCreateInstance(ref Guid clsid, ref Guid iid, [MarshalAs(UnmanagedType.Interface)] out object ptr); [ComImport, Guid("D332DB9E-B9B3-4125-8207-A14884F53216"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface ICLRMetaHost { [return: MarshalAs(UnmanagedType.Interface)] object GetRuntime(string version, ref Guid iid); // Rest omitted } [ComImport, Guid("BD39D1D2-BA2F-486a-89B0-B4B0CB466891"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface ICLRRuntimeInfo { void GetVersionString(char[] buffer, int bufferLength); void GetRuntimeDirectory(char[] buffer, int bufferLength); bool IsLoaded(IntPtr hProcess); void LoadErrorString(uint id, char[] buffer, int bufferLength, int lcid); void LoadLibrary(string path, out IntPtr hMdodule); void GetProcAddress(string name, out IntPtr addr); [return: MarshalAs(UnmanagedType.Interface)] object GetInterface(ref Guid clsid, ref Guid iid); bool IsLoadable(); void SetDefaultStartupFlags(uint flags, string configFile); void GetDefaultStartupFlags(out uint flags, char[] configFile, int configFileLength); void BindAsLegacyV2Runtime(); void IsStarted(out bool started, out uint flags); } [ComImport, Guid("CB2F6722-AB3A-11d2-9C40-00C04FA30A3E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface ICorRuntimeHost { void CreateLogicalThreadState(); void DeleteLogicalThreadState(); void SwitchinLogicalThreadState(IntPtr cookie); void SwitchoutLogicalThreadState(out IntPtr cookie); void LocksHeldByLogicalThread(out int count); void MapFile(IntPtr hFile, out IntPtr address); void GetConfiguration(out IntPtr config); void Start(); void Stop(); void CreateDomain(string name, object identity, out _AppDomain domain); void GetDefaultDomain(out _AppDomain domain); void EnumDomains(out IntPtr hEnum); void NextDomain(IntPtr hEnum, out _AppDomain domain); void CloseEnum(IntPtr hEnum); // rest omitted } } 

样品用法:

 class Program { static void Main(string[] args) { AppDomain.CreateDomain("Example"); foreach (var domain in CLRUtil.EnumAppDomains()) { Console.WriteLine("Found appdomain {0}", domain.FriendlyName); } Console.ReadLine(); } } 

输出:

 Found appdomain ConsoleApplication1.vshost.exe Found appdomain Example