Поделиться через


How a .Net application loads a .Net COM class

In .NET COM, do you know how AppDomain::LoadCOMClass() works?

In CLR 4.0, it’s clr!AppDomain::LoadCOMClass()

In .NET 2.0, it’s mscorwks!AppDomain::LoadCOMClass()

In 2.0 & 4.0 (or above) it first checks the shim info which is retrieving the class name and other information associated with a given GUID in a component's manifest. This is done by calling SxsLookupClrGuid.

The following is a sample component manifest declaring a CLR GUID and a CLR surrogate that SxsLookupClrGuid can look up:

<assembly manifestVersion="1.0" xmlns=

"urn:schemas-microsoft-com:asm.v1">

<assemblyIdentity type="interop" name=

"DotNet.Sample.Surrogates" version="1.0.0.0"/>

<clrClass name="MySampleClass" clsid=

"{19f7f420-4cc5-4b0d-8a82-c24645c0ba1f}"

progId="MySampleClass.1" runtimeVersion="1.0.3055"/>

<clrSurrogate name="MySampleSurrogate" clsid=

"{fdb46ca5-9477-4528-b4b2-7f00a254cdea}"

runtimeVersion="1.0.3055"/>

</assembly>

If SxsLookupClrGuid succeeds, in .Net 2.0 it loads the assembly & type information using a code similar to the one below.

 

Assembly retAssembly = null;

retAssembly = System.Reflection.Assembly.LoadFile(@"….\\COMClass.dll");

Type dtType = retAssembly.GetType("<CLASS NAME>", false, false);

 

If SxsLookupClrGuid succeeds, in .Net 4.0 & above, it checks if the assembly is a PIA (Primary Interop Assembly) or not.

The PIA check is done by looking for mscoree.dll in the registry (under CLSID\InprocServer32) or if it was specified as <clrSurrogate> in the manifest.

If a registry search was performed and if mscoree.dll is present in the registry then the type is not PIA.

For side by side, a registry lookup is not performed and PIA is true if the type name was specified as <clrSurrogate> in the manifest, in which case it is treated as registration free PIA.

In any case, if PIA is true, the assembly & type information is loaded using a code similar to the above.

 

In case SxsLookupClrGuid fails in .Net 2.0, registry is searched. If the CLSID information is found in the registry it populates the class, assembly and codebase and loads the assembly and type using the above code. Otherwise you get the conventional error saying “Class not registered” (Retrieving the COM class factory for component with CLSID {xxx} failed due to the following error: 80040154.").

In case SxsLookupClrGuid fails in .Net 4.0 & above, registry is searched. If the CLSID information is found in the registry it populates the class, assembly and codebase.

Then it checks if the assembly is PIA or not. If PIA, load the assembly using the above code. If it is not a PIA, it checks in the registry if the runtime information (RuntimeVersion entry under the CLSID) is present or not. If present then it checks if the application uses the same runtime. If not, it does not load the assembly and returns NULL. If the runtime is the same, it loads the assembly using the same above code.

When a NULL is returned the result is using the default System.__ComObject type.

 

Notes on PIA (Primary Interop Assembly)

=======================================

Primary interop assemblies must meet the following requirements:

 

  • Include all COM types defined in the original type library and maintain the same GUID identities.
  • Be signed with a strong name using standard public key cryptography.
  • Contain the PrimaryInteropAssemblyAttribute attribute.
  • Avoid redefining external COM types.
  • Reference only other primary interop assemblies for external COM dependencies.

 

Reference on PIA:

https://msdn.microsoft.com/en-us/subscriptions/hfac4fky(v=vs.80)

 

Thanks,

 

Shamik Misra