Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List AppDomains in Process

Is there any possibility how to enumerate AppDomains within Process?

like image 872
marc Avatar asked Dec 23 '08 10:12

marc


2 Answers

You may want to look at this post

using System.Runtime.InteropServices;
// Add the following as a COM reference - C:\WINDOWS\Microsoft.NET\Framework\vXXXXXX\mscoree.tlb
using mscoree;                              

        public static IList<AppDomain> GetAppDomains()
        {
            IList<AppDomain> _IList = new List<AppDomain>();
            IntPtr enumHandle = IntPtr.Zero
            CorRuntimeHostClass host = new mscoree.CorRuntimeHostClass();
            try
            {
                host.EnumDomains(out enumHandle);
                object domain = null;
                while (true)
                {
                    host.NextDomain(enumHandle, out domain);
                    if (domain == null) break;
                    AppDomain appDomain = (AppDomain)domain;
                    _IList.Add(appDomain);
                }
                return _IList;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return null;
            }
            finally
            {
                host.CloseEnum(enumHandle);
                Marshal.ReleaseComObject(host);
            }
        } 
    }
like image 161
Brann Avatar answered Sep 23 '22 21:09

Brann


UPDATE

You can add the interface ICorRuntimeHost as:

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace mscoree
{
    [CompilerGenerated]
    [Guid("CB2F6722-AB3A-11D2-9C40-00C04FA30A3E")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [TypeIdentifier]
    [ComImport]
    [CLSCompliant(false)]
    public interface ICorRuntimeHost
    {
        void _VtblGap1_11();

        void EnumDomains(out IntPtr enumHandle);

        void NextDomain([In] IntPtr enumHandle, [MarshalAs(UnmanagedType.IUnknown)] out object appDomain);

        void CloseEnum([In] IntPtr enumHandle);
    }
}

And add a method:

private static ICorRuntimeHost GetCorRuntimeHost()
{
    return (ICorRuntimeHost)Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("CB2F6723-AB3A-11D2-9C40-00C04FA30A3E")));
}

Then you don't need the mscoree.tlb reference. And make some changes as:

using mscoree;
ICorRuntimeHost host = null;
host = GetCorRuntimeHost();

It's my current code for this problem.


Original answer

I refine it as this:

using System.Runtime.InteropServices;
using mscoree;

public static IEnumerable<AppDomain> EnumAppDomains()
{
    IntPtr enumHandle = IntPtr.Zero;
    CorRuntimeHostClass host = null;

    try
    {
        host = new CorRuntimeHostClass();
        host.EnumDomains(out enumHandle);
        object domain = null;

        host.NextDomain(enumHandle, out domain);
        while (domain != null)
        {
            yield return (AppDomain)domain;
            host.NextDomain(enumHandle, out domain);
        }
    }
    finally
    {
        if (host != null)
        {
            if (enumHandle != IntPtr.Zero)
            {
                host.CloseEnum(enumHandle);
            }

            Marshal.ReleaseComObject(host);
        }
    }
}

Call it as this:

foreach (AppDomain appDomain in EnumAppDomains())
{
    // use appDomain
}

Remember to reference COM object \WINDOWS\Microsoft.NET\Framework\vXXX\mscoree.tlb, set reference mscoree "Embed Interop Types" as "False".

like image 42
ChrisTorng Avatar answered Sep 25 '22 21:09

ChrisTorng