csharp/Albo1125/Albo1125-Common/Albo1125.Common/AppDomainHelper.cs

AppDomainHelper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Albo1125.Common
{
    //Thank you LMS for your help in writing this clast.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.InteropServices;

    using mscoree;

    [Serializable]
    public clast AppDomainHelper
    {

        public delegate void CrossAppDomainCallDelegate(params object[] payload);
        public delegate object CrossAppDomainCallRetValueDelegate(params object[] payload);

        public static AppDomain GetAppDomainByName(string name)
        {
            return GetAppDomains().FirstOrDefault(appDomain => appDomain.FriendlyName == name);
        }

        public static void InvokeOnAppDomain(AppDomain appDomain, CrossAppDomainCallDelegate targetFunc, params object[] payload)
        {
            appDomain.SetData(appDomain.FriendlyName + "_payload", payload);
            appDomain.SetData(appDomain.FriendlyName + "_func", targetFunc);
            appDomain.DoCallBack(InvokedOnAppDomain);
        }

        public static T InvokeOnAppDomain(AppDomain appDomain, CrossAppDomainCallRetValueDelegate targetFunc, params object[] payload)
        {
            appDomain.SetData(appDomain.FriendlyName + "_payload", payload);
            appDomain.SetData(appDomain.FriendlyName + "_func", targetFunc);
            appDomain.DoCallBack(InvokedOnAppDomainRet);

            return (T)Convert.ChangeType(appDomain.GetData("result"), typeof(T));
        }

        private static void InvokedOnAppDomain()
        {
            AppDomain currentAppDomain = AppDomain.CurrentDomain;
            string name = currentAppDomain.FriendlyName;

            // Grab payload.
            object[] payload = (object[])currentAppDomain.GetData(name + "_payload");
            CrossAppDomainCallDelegate func = (CrossAppDomainCallDelegate)currentAppDomain.GetData(name + "_func");

            func.Invoke(payload);
        }

        private static void InvokedOnAppDomainRet()
        {
            AppDomain currentAppDomain = AppDomain.CurrentDomain;
            string name = currentAppDomain.FriendlyName;

            // Grab payload.
            object[] payload = (object[])currentAppDomain.GetData(name + "_payload");
            CrossAppDomainCallRetValueDelegate func = (CrossAppDomainCallRetValueDelegate)currentAppDomain.GetData(name + "_func");

            object result = func.Invoke(payload);
            currentAppDomain.SetData("result", result);
        }

        public static IList GetAppDomains()
        {
            IList domains = new List();
            IntPtr enumHandle = IntPtr.Zero;
            ICorRuntimeHost host = new CorRuntimeHost();

            try
            {
                host.EnumDomains(out enumHandle);
                while (true)
                {
                    object domain;
                    host.NextDomain(enumHandle, out domain);
                    if (domain == null) break;
                    AppDomain appDomain = (AppDomain)domain;
                    domains.Add(appDomain);
                }

                return domains;
            }
            finally
            {
                host.CloseEnum(enumHandle);
                Marshal.ReleaseComObject(host);
            }
        }
    }
}