Registering a .NET COM library as part of an add-in

Add-in Express™ Support Service
That's what is more important than anything else

Registering a .NET COM library as part of an add-in
 
nwein




Posts: 577
Joined: 2011-03-28
I have the same question as https://www.add-in-express.com/forum/read.php?FID=5&TID=7183 from almost 10 years ago, though I don't understand how to make it work.
In my solution, I have a project that I mark as ComVisible = true, within it are various classes, all marked as ComVisible as well, as well as ClassInterface and ComSourceInterface.
When building that project (note - this is not the add-in project) it generates a tlb file as expected.
I reference that project in my add-in project, and when publishing my add-in, both the .dll and .tlb are shipped with it.
If I then open Excel for example, I can reference the tlb in the references dialog and have access to all my objects and methods etc. All fine and good. However, I need to always find the path of that tlb, which is not ideal (especially given that it's a clickOnce and hence the path keeps changing with every release).
I've tried marking the COM dll as a COMLibrary when publishing my add-in, but that doesn't seem to register it on machines that install my add-in.
From reading many comments from you guys, it seems like it's possible to register my tlb/dll so that it would be available without having to specify the location of it (i.e. registered in the GAC, similar to what regasm /tlb is doing) - can you describe the actual steps to make it happen? Hopefully it doesn't include a kludge like writing my own code to invoke regasm within the add-in...
Thanks in advance!

P.S
I can't seem to mark my COM library as isolated in my add-in references (the Isolated property is not available)
Posted 22 Jan, 2020 10:17:57 Top
Andrei Smolin


Add-in Express team


Posts: 18823
Joined: 2006-05-11
Hello Nir,

When using COMLibrary, this is Add-in Express who registers the classes; you can check this. But, Add-in Express doesn't write any TLB info in the keys createв. Accordingly, you need to find these keys and modify them. If you do not use COMLibrary, you'll need to create and delete these keys yourself; use an event of the ClickOnce module to do this.

When creating/updating the keys, we suggest that you avoid determining the Office bitness. Instead, you should create these keys in 32bit and 64bit registries. See https://docs.microsoft.com/en-us/dotnet/api/microsoft.win32.registryview?view=netframework-4.0.

The keys should be created in HKCU, not in HKLM. Remember that HKCR is a mixture of HKCU and HKLM keys.


Andrei Smolin
Add-in Express Team Leader
Posted 24 Jan, 2020 04:14:57 Top
nwein




Posts: 577
Joined: 2011-03-28
Thanks for the reply, however, I just tested it, and although I'm marking my library (.dll, not the .tlb) as a COMLibrary in the clickonce publish dialog, I can't find that library guid anywhere in my registry (when the add-in is installed on another machine that is).
When using COMLibrary, this is Add-in Express who registers the classes

where does it register it to? what kind of registration is it doing? is it similar to what regasm /codebase is doing?
If that's the case (though I can't see happening) then i'm fine and I don't care about the tlb, but that doesn't seem to be the case.
But, Add-in Express doesn't write any TLB info in the keys createв. Accordingly, you need to find these keys and modify them

Again, what (registry) keys and how should I modify those keys if I do want to include the TLB info?
Really, my ultimate goal is to have my COM library be available in the reference dialog without having to manually add it myself.
As far as I understand (and I'm most likely wrong), to achieve this one need to either regasm /codebase myLibrary.dll or regasm /tlb myLibrary.dll or have the myLibrary.dll in the GAC somehow, no? does ADX do any of those in any way?
I understand that I can execute any code (like regasm, or directly writing registry keys in code) in a ClickOnce module, but i'd like to not write any custom code if it's not needed, especially if you guys already support this in a way, but from what I can gather, I don't really see it working.

I'm using ADX 9.4.4644.0
Posted 24 Jan, 2020 11:30:57 Top
Andrei Smolin


Add-in Express team


Posts: 18823
Joined: 2006-05-11
Hello Nir,

nwein writes:
although I'm marking my library (.dll, not the .tlb) as a COMLibrary in the clickonce publish dialog


Also, the assembly must be COM visible.

nwein writes:
I don't care about the tlb


For a program to use a COM class, the class must be registered. The following is required for the underlying program layers to be able to *find* the registered COM class:
- A .TLB must be present; it is possible to live without that file but this requires using other files such as .EXE, .DLL or .OLB; I assume these options are unavailable or useless for us.
- A registry key describing the .TLB must be in HKEY_CURRENT_USER\Software\Classes\TypeLib\{type lib GUID here}; an example is HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{00020430-0000-0000-C000-000000000046}\2.0; since your add-in is per-user, the .TLB should be in HKCU, not HKLM (otherwise, you'll need admin privileges to create this key).
- The COM class registration must contain a pointer to the typelib key; an example would be the key TypeLib under HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{000C1090-0000-0000-C000-000000000046} (it's Microsoft Windows Installer); again, your classes should be registered in HKCU otherwise admin permissions are required to register it.


Andrei Smolin
Add-in Express Team Leader
Posted 27 Jan, 2020 04:34:54 Top
nwein




Posts: 577
Joined: 2011-03-28
Thanks for the more detailed explanation.
Just to clarify:
Also, the assembly must be COM visible.

The assembly is COM visible, i.e.
[assembly: ComVisible(true)]

This is in addition to marking all my classes within that assembly as ComVisible(true) (i.e.
[ComVisible(true)]public class MyClass{...}
)
Finally, that assembly has the 'Register for COM interop' option checked in the project build properties.
That assembly has an assembly guid (i.e.
[assembly: Guid("c3f4dd50-be86-4dfa-8e12-94a9625a911f")]
) though I did not assign individual guids to each class within that assembly.
So just to confirm, with the above setup, the way I understand it from your description, I should have this key:
HKEY_CURRENT_USER\Software\Classes\TypeLib\{c3f4dd50-be86-4dfa-8e12-94a9625a911f} (not sure what should be underneath that key though, also not sure how is this key is supposed to be created. Manually by me? by Add-in express?)
And the pointer to that key at:
HKEY_CURRENT_USER\SOFTWARE\Classes\CLSID\{c3f4dd50-be86-4dfa-8e12-94a9625a911f} (or is that guid need to be different? perhaps the guid of my add-in's AddinModule?)
Is it possible for you to provide a simple add-in that will exhibit that behavior (an add-in solution with one addin module project, and one class library marked as COM project, referenced by the add-in project)?
I'm still at loss...
Posted 27 Jan, 2020 09:13:34 Top
Andrei Smolin


Add-in Express team


Posts: 18823
Joined: 2006-05-11
nwein writes:
Finally, that assembly has the 'Register for COM interop' option checked in the project build properties.


This creates the typelibrary. Use this to obtain a copy of the .TLB file. Before you clear this option and rebuild the assembly, check below.

nwein writes:
HKEY_CURRENT_USER\Software\Classes\TypeLib\{c3f4dd50-be86-4dfa-8e12-94a9625a911f}


No. While the type library is registered, you can copy the .tlb file and use it for deployment. As to registering it, check if this page helps: https://stackoverflow.com/questions/23487332/how-to-programmatically-register-set-correct-path-to-a-type-library-from-withi.


Andrei Smolin
Add-in Express Team Leader
Posted 28 Jan, 2020 09:17:49 Top