Using .Net (CLR Managed) Classes in Win32 Applications | how-to | home |
.Net has special code to expose managed classes as COM objects. Normally to use a .Net assembly through COM you need to register the assembly using REGASM.EXE. Starting with Windows XP sp1 win32 side-by-side has special provisions for registration-free accessing of .Net classes using COM.
A new manifest entry, <clrClass> declares the name, class ID and, optionally, ProgID of a class that can be accessed from Win32 through COM. The CLR assembly that implements the class is found by CLR (fusion) using the manifest identity from the Win32 manifest. This means that the CLR assembly identity (name, version and public key token) must be the same as the corresponding values in the win32 manifest. It also means that if the manifest is not embedded in the DLL, the search will fail if the DLL is found sooner then the manifest file. Note that if both are in the same folder, the DLL is checked before the manifest. The side effect of this is that if a CLR assembly is installed in GAC (Global Assembly Cache), Win32 will never find the manifest unless it is installed as a shared Win32 assembly (in %systemroot%\WinSxS).
Microsoft's recommendation for preparing CLR-managed classes for use with COM is to embed the win32 manifest in the DLL as a win32 resource. See MSDN for details...
However this is not always practical, particularly if you do not own the source code or the right to modify it.
Manifest Maker supports building win32 manifests for CLR classes in both Automatic and CLR (.Net) Class Win32 Manifest build types. In both cases each CLR assembly DLL is placed in a subdirectory of the target directory and the corresponding CLR manifest is written to the target directory. This is different from Win32 assemblies where the manifest must be in the same folder as all files referenced in that manifest.
Use the Automatic build type if you are building manifests for a Win32 program. Use the CLR (.Net) Class Win32 Manifest build type when you need to use the CLR class manifest for a more elaborate configuration.
Important Note:
You should only build manifests for those assemblies you want to access from win32 code using COM. Any other assemblies need to be located where CLR (.Net) expects to find them. Specifically any assemblies needed by assemblies in your project must be manually placed in appropriate folders. This usually means in the subfolder created by Manifest Maker for the CLR DLL used in the project.
Example:
Suppose you have the following files:
You should add the first two files to the project and choose Automatic build. The build may fail with a message that the example.managed.class.dll could not be loaded because dependent assemblies are missing. Copy the helper.managed.code.dll to the example.managed.class subdirectory created by Manifest Maker for the example.managed.class.dll. Click the Build button again - this time the build succeeds. Also see fusion logsbelow.
| Directory | Extension |
|---|---|
| C:\Windows\WinSxS\manifests\ | .manifest |
| C:\Windows\assembly\GAC\ | .DLL |
| (application directory) | .DLL |
| (application directory) | .MANIFEST |
| (application directory)\(assembly directory) | .DLL |
| (application directory)\(assembly directory) | .MANIFEST |
For more details on assembly search sequence read Assembly Searching Sequence on MSDN...
| Directory | Extension |
|---|---|
| C:\Windows\assembly\GAC\ | .DLL |
| (application directory) | .DLL |
| (application directory)\(assembly directory) | .DLL |
| (application directory) | .EXE |
| (application directory)\(assembly directory) | .EXE |
For more details on configuring CLR assembly loading read Runtime Settings Schema on MSDN...
The above rules generally also apply to IIS6-based applications (read more...)
The CLR (.Net) loader, called Fusion, can write detailed logs of CLR assembly search and loading. This is an invaluable tool for diagnosing assembly loading problems. To turn on Fusion logs:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion] "ForceLog"=dword:00000001 "LogResourceBinds"=dword:00000001 "LogFailures"=dword:00000001 "LogPath"="C:\\Temp\\FusionLogs"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion] "ForceLog"=- "LogResourceBinds"=- "LogFailures"=- "LogPath"=-
You can read more about .Net Framework tools on MSDN.
You may also wish to read Using .Net (CLR Managed) Classes in IIS6
Excellent blog post by Junfeng Zhang Registration Free COM/.Net interop