Freigeben über


How to loop through the app-domains in the current process

Consider a scenario where we have a VSTO add-in and an automation add-in for Excel and we want to share some objects from the VSTO addin to the Automation add-in. Because the VSTO add-in is loaded in its own separate appdomain and the automation add-in is loaded in the different(default) appdomain, sharing objects is not that easy. One way to share objects could be to use "RequestCOMAutomationService" method as described in the following blog article:

https://blogs.msdn.com/andreww/archive/2008/08/11/why-your-comaddin-object-should-derive-from-standardolemarshalobject.aspx

However, by using the above mentioned method, the object would be shared "ByVal". What if we want to share the objects "ByRef"

One of the solution to share objects "ByRef" is to use appdomain's "CreateInstanceAndUnwrap" method to create objects and to get the proxy objects. However to use "CreateInstanceAndUnwrap" method we need reference to the appdomain in which the actual objects will be created.

In our scenario we need to have reference to the VSTO appdomain so that we can create objects in it and can obtain proxy objects in the automation appdomain.

 

Since VSTO appdomain is automatically created by VSTO runtime, we do not have reference to it. We need a way to loop through the appdomain present in the current process (Excel) and get a reference to the VSTO appdomain.

To find the VSTO Appdomain (in a collection of appdomains), we will use its name. To find the VSTO appdomain's name, in the VSTO add-in code, we can use following code:

AppDomain ad = System.Threading.Thread.GetDomain();
String VSTO_AppDomain_Name = ad.FriendlyName.ToString();

This VSTO appdomain name can be shared with the Automation add-in using the RequestCOMAutomationService technique mentioned above or by using any other way.

Although there is no managed API which enables us to loop through the appdomains, there is a way to loop through the app-domains in a process. The following code can be used to loop through the appdomains and to get reference to the VSTO appdomain:

 using System.Runtime.InteropServices; 
using mscoree; 
AppDomain VSTOAppDomain = null; 

private void FindVSTOAppDomain(string VSTOAppDomainName) 
{ 
    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 ad = (AppDomain)domain; 
            if (ad.FriendlyName.Equals(VSTOAppDomainName)) 
            { 
                VSTOAppDomain = ad; 
            } 
        } 
    } 
    catch (Exception ex) 
    { 

    } 
}

 

    To use above code we need to add COM reference to the mscoree.tlb to the project. mscoree.tlb can be located at:

"C:\WINDOWS\Microsoft.NET\Framework\vXXXXXX\mscoree.tlb".

 

For more information, please refer to: https://blogs.msdn.com/jackg/archive/2007/06/11/enumerating-appdomains.aspx