2

I have a C# library project which is designed to be used from unmanaged C++ code via COM. enter image description here

Only 2 or 3 methods are going to be called in this way but I get warnings like this:

warning : Type library exporter warning processing ''. Warning: Type library exporter encountered a generic type instance in a signature. Generic code may not be exported to COM.

These properties and methods are not designed to be accessed from C++, an in fact they are not even public methods so they (surely) wouldn't be visible anyway.

Two questions really:

  • Q1: How can I control what is exported? Access modifiers on classes/methods or something else?
  • Q2: How can I see what is exported e.g. check what's in the type library to see if I missed something

It would be nice to double check I'm not bloating my type-library with a load of stuff that's not supposed to be there...

3
  • 1
    The assembly should have ComVisible(false) so it's the default value, and then put ComVisible(true) on "things" (classes, methods, etc.) you want to export. learn.microsoft.com/en-us/dotnet/api/… To check what's in a .tlb, use OleView from Windows SDK Commented Jun 18, 2020 at 14:23
  • @SimonMourier is the checkbox above still supposed to be checked if anything should be COM-visible, is that controlling the ComVisible status of the assembly? Otherwise I'm not sure where I apply it on the assembly itself. BTW this basically is the answer to my quesiton, I think, if you care to write it as an answer Commented Jun 18, 2020 at 14:41
  • 1
    The "register for COM Interop" is about registration (regasm), it not strictly related to what's exposed. Commented Jun 18, 2020 at 14:51

1 Answer 1

2

I can declare the whole assembly to be invisible to COM, like this (in fact when you use Visual Studio C# class library template it should put it itself in AssemblyInfo.cs):

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components.  If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

Now, in each class I can decide it will be visible to COM or not like here:

using System;
using System.Runtime.InteropServices;

namespace ClassLibrary1
{
    [ProgId("MyCoolClass")]
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class MyCoolVisibleClass
    {
        public void SayHello()
        {
            Console.WriteLine("Hello COM world");
        }

        // explicit non COM visible because it's set to true at class level
        [ComVisible(false)]
        public void SayHello2()
        {
            Console.WriteLine("Hello world");
        }
    }

    // implicit non COM visible
    public class MyCoolInvisibleClass
    {
        public void SayHello()
        {
            Console.WriteLine("Hello world");
        }
    }
}

You can use the project properties to register ("Register for COM Interop" checkbox) , but I personally register myself with a command line like this (for 64-bit registry world):

%windir%\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe ClassLibrary1.dll /codebase /tlb

This outputs something like this:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe ClassLibrary1.dll /codebase /tlb
Microsoft .NET Framework Assembly Registration Utility version 4.8.3752.0
for Microsoft .NET Framework version 4.8.3752.0
Copyright (C) Microsoft Corporation.  All rights reserved.

RegAsm : warning RA0000 : Registering an unsigned assembly with /codebase can cause your assembly to interfere with other applications that may be installed on the same computer. The /codebase switch is intended to be used only with signed assemblies. Please give your assembly a strong name and re-register it.
Types registered successfully
Assembly exported to 'D:\KilroyWasHere\ClassLibrary1.tlb', and the type library was registered successfully

And I can check what's really inside the .tlb using OleView from Windows SDK:

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.