When you create a reg-free managed COM object, how can I get the CLR to search in a directory other than the main application executable?

This is a kind of complex question, striking several mysterious areas related to COM, CLR, and COM to no avail.

Firstly, my main application is written in python. Thus, this code base (in development) has, say, C: \ mainapp \ main.py.

Of course, on Windows, this is the program C: \ Python27 \ python.exe, which executes the program.

Now I want to use reg-free COM from python (using win32com) to talk (using IDispatch) for a COM object written in C # that I control, which is located in C: \ mainapp \ ManagedCOMObject.dll


Note. If you don't speak python / pythoncom, note that calling Dispatch () ultimately boils down to CoCreateInstance ().


Attempt 1

#main.py: import win32com.client CLSID_ManagedComObject_MyClass = "{zzzzz....}" #This is correct myclass = win32com.client.Dispatch(CLSID_ManagedComObject_MyClass) 

Result

Failure, because the object is not in the registry (as expected), and I donโ€™t mention anything about the manifest files, and the python.exe manifest obviously does not know about my object.


Attempt 2

 #main.py: ac = ActivationContext("C:\mainapp\myapp.manifest", asm_dir="C:\mainapp") with ac.activate(): #The above two lines fill in a ACTCTX structure, call CreateActCtx, and call ActivateActCtx import win32com.client CLSID_ManagedComObject_MyClass = "{zzzzz....}" #This is correct myclass = win32com.client.Dispatch(CLSID_ManagedComObject_MyClass) 

-

 #myapp.manifest: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity type="win32" name="My.Main.App" version="1.0.0.0" processorArchitecture="x86" /> <dependency> <dependentAssembly> <assemblyIdentity name="ManagedComObject" version="1.0.0.0" processorArchitecture="msil" /> </dependentAssembly> </dependency> </assembly> 

Note that ManagedCOMObject has a built-in manifest that declares a COM object using the clrClass tag.

Result

Invoking ActicateActCtx successfully and correctly parses the manifests myapp.manifest and ManagedComObject.dll. - I checked this with sxstrace.exe

A call to CoCreateInstance fails with FileNotFound, after checking for C: \ Python27 \ ManagedComObject.dll. The magazine claims that PrivatePath merge is not installed (presumably since python.exe.config does not exist), and just does not look at the C # object in C:. \ Mainapp

Questions

  • Why is this failing? I believe this is because the CLR COM bootloader stub cannot import my C # assembly. If this failed before this step, the CLR will not even boot, so the fact that it examines and creates merge logs leads me to verification, because the CLR cannot find ManagedCOMObject.dll.

  • Please note that the CLR is loaded - I believe this means that COM successfully looked at the current activation context to find the registration. I donโ€™t know exactly what clrClass does in the manifest, but presumably it got the CLR loaded successfully.

  • I assume the problem is that the CLR does not pay attention to ActCtx when loading assemblies. If I wrote managed code, I could connect to the AppDomain.CurrentDomain.AssemblyResolve event and find the DLL myself. So instead of writing unmanaged code and hosting the CLR only implicitly, can I somehow modify the PrivatePath application and / or how are the nodes polled?

+4
source share
1 answer

I assume the problem is that the CLR does not pay attention to ActCtx when loading assemblies

Yes this is correct. The CLR has its own strategy for finding assemblies that are otherwise not affected by the Windows activation context. By default, it appears only in the GAC, and then in the private bin path in the EXE. This can be seen when working with the program Fuslogvw.exe.

You don't have many great options here. Installing an assembly in the GAC is an obvious solution and is generally suitable for [ComVisible] assemblers because it helps solve the COM DLL Hell problem. Only what you can do is copy it to the C: \ Python27 directory or write the python.exe.config file in the same directory, which changes the verification path to the C: \ Python27 subdirectory. Neither itch well. The CLR hosting itself or the AppDomain.AssemblyResolve event handler record are outside the table.

Using the GAC is the right solution if you want to avoid Regasm.exe / codebase

+2
source

All Articles