2015-11-24 9 views
5

mscoreeを参照せずにすべてのプロセスのドメインを列挙する方法出来ますか?私はインターネットのどこかで2007年から何らかの解決策を見つけました。しかし、それは列挙し、空のコレクションです。mscoreeなしですべてのAppDomainsを列挙する

は、ここでは、コードです:

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

答えて

9

参照していない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 
+0

卿、あなたは紳士です!ありがとう! – Nickon