.net 列出正在处理的 AppDomains

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/388554/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 10:52:38  来源:igfitidea点击:

List AppDomains in Process

.netprocessappdomain

提问by marc

Is there any possibility how to enumerate AppDomains within Process?

是否有可能如何在 Process 中枚举 AppDomains?

回答by Brann

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

回答by ChrisTorng

UPDATE

更新

You can add the interface ICorRuntimeHostas:

您可以将接口添加ICorRuntimeHost为:

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:

那么您就不需要 mscoree.tlb 参考。并进行一些更改:

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".

请记住引用 COM 对象 \WINDOWS\Microsoft.NET\Framework\vXXX\mscoree.tlb,将引用 mscoree“Embed Interop Types”设置为“False”。

回答by Stefan Steiger

VB.NET:

VB.NET:

<System.Runtime.CompilerServices.CompilerGenerated>
<System.Runtime.InteropServices.Guid("CB2F6722-AB3A-11D2-9C40-00C04FA30A3E")>
<System.Runtime.InteropServices.InterfaceType(Runtime.InteropServices.ComInterfaceType.InterfaceIsIUnknown)>
<System.Runtime.InteropServices.ComImport>
<System.CLSCompliant(False)>
Interface ICorRuntimeHost
    Sub _VtblGap1_11()
    Sub EnumDomains(<System.Runtime.InteropServices.Out> ByRef enumHandle As IntPtr)
    Sub NextDomain(<System.Runtime.InteropServices.[In]> ByVal enumHandle As IntPtr, <System.Runtime.InteropServices.Out> <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.IUnknown)> ByRef appDomain As Object)
    Sub CloseEnum(<System.Runtime.InteropServices.[In]> ByVal enumHandle As IntPtr)
End Interface

Private Function GetCorRuntimeHost() As ICorRuntimeHost
    Return CType(Activator.CreateInstance(System.Type.GetTypeFromCLSID(New Guid("CB2F6723-AB3A-11D2-9C40-00C04FA30A3E"))), ICorRuntimeHost)
End Function

Public Function GetAppDomains() As List(Of AppDomain)
    Dim ls As List(Of AppDomain) = New List(Of AppDomain)
    Dim enumHandle As IntPtr = IntPtr.Zero

    Dim host As ICorRuntimeHost = GetCorRuntimeHost()

    Try
        host.EnumDomains(enumHandle)
        Dim domain As Object = Nothing

        While True
            host.NextDomain(enumHandle, domain)
            If domain Is Nothing Then Exit While
            Dim appDomain As AppDomain = CType(domain, AppDomain)
            ls.Add(appDomain)
        End While

        Return ls
    Catch e As Exception
        Console.WriteLine(e.ToString())
        Return Nothing
    Finally
        host.CloseEnum(enumHandle)
        Runtime.InteropServices.Marshal.ReleaseComObject(host)
    End Try
End Function

Usage:

用法:

Dim ls As List(Of AppDomain) = GetAppDomains()
System.Console.WriteLine(ls)