2015-11-24 39 views
5

mscoree referansına bakmadan tüm süreç 'etki alanları nasıl numaralandırılır. Mümkün mü? İnternette 2007 yılında bir yerde bir çözüm buldum. Ama numaralandırır ve boş koleksiyon.Tüm AppDomains'i mscoree olmadan numaralandır

İşte kod:

public static class DomainHelper 
{ 
    public static AppDomain[] LoadedDomains 
    { 
     get 
     { 
      var loadedDomains = new List<AppDomain>(); 
      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(); 
    } 
} 

cevap

9

başvuran Değil mscoree.tlb sıkıntı içine almak budur, ICorRuntimeHost yanlış ilan edilir. Yöntem sırası tamamen karışık, ne olduğunu açık değil. Hayat 2007'de çok daha kolaydı, hosting arayüzü .NET 4.0 için büyük ölçüde yeniden tasarlandı ve ICorRuntimeHost kullanımdan kaldırıldı. Yine de, hala bir süre için çalışıyor.

.NET 4.0 ve sonraki sürümlerinde çalışan kod yayınlayacağım. Uygun yaklaşım, ICLRMetaHost ile başlamaktır. Ardından, ilgilendiğiniz çalışma zamanı örneği için ICLRRuntimeInfo örneğini elde edin. .NET 4.0'ın CLR'nin süreç içinde yan yana anlatımını desteklediğini unutmayın, kodunuzun kullandığını bulmak isteyeceksiniz. ICLRRuntimeInfo :: GetInterface() yöntemi, bir örneği eski ICorRuntimeHost arabirimine döndürür.

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 
    } 
} 

Örnek kullanım:

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(); 
    } 
} 

Çıktı:

Found appdomain ConsoleApplication1.vshost.exe 
Found appdomain Example 
+0

Efendim, bir beyefendi vardır! Teşekkürler! – Nickon