1

I have a library that is a part of a larger application. Our automated testing and regression suite is a Ruby project. I already know how to access COM visible DLLs in Ruby. What I would like to do however is to generate both, a COM visible binary and a non COM visible binary during the Visual Studio build process. It doesn't really matter what is made visible in the COM visible DLL as its for purely internal use. All of it could, and probably would be best if it was. I see I can set a value in the AssemblyInfo.cs to make everything visible however, like I said, I would need one of each.

Is there a way to do this without manually writing a wrapper around the C# project's functions?

5
  • "What I would like to do however is to generate both, a COM visible binary and a non COM visible binary during the Visual Studio build process" -- to clarify, you want to use the same code to generate one COM-visible, and one non-COM-visible DLL? Commented Feb 6, 2015 at 22:18
  • Yes, that is correct. If the setting in AssemblyInfo.cs does what I think it does would it not create a com visible dll? I just want both versions Commented Feb 6, 2015 at 22:34
  • There's just no point to it, a [ComVisible] assembly or class just has an attribute, that's all. It doesn't come to life until you register it and the COM interop built-in to the CLR starts doing its job. That code is not in your assembly, it is located in mscoree.dll. Using a [ComVisible] assembly as a normal .NET assembly makes it behave like any other, you can't tell the difference. Commented Feb 6, 2015 at 22:44
  • 1
    @Hans the only reason I could think of for doing this would be if a developer wanted to distribute one DLL that is not COM-registerable. Commented Feb 6, 2015 at 22:54
  • @transistor1 That is exactly why I want to do this. It is not a requirement for this to be COM visible for distribution however it is very useful within our test framework to share this library while testing other parts of our application stack. I don't have to "ask" if its to do this for the test case but I might if it went to production. Commented Feb 9, 2015 at 14:40

2 Answers 2

2

You can create additional configuration to your project. For this configuration define some definition (e.g. COM_VISIBLE). This can be defined in Project Properties->Build->Conditional compilation symbols

Then, in AssemblyInfo.cs you may use #if directive:

#if COM_VISIBLE
    [assembly:ComVisible(true)]
#endif 
Sign up to request clarification or add additional context in comments.

1 Comment

On this, is there a way of avoiding requiring I register the DLL? One of my goals was to eliminate having to run an installer on any boxes. I wanted to just include the DLLs in my ruby project and call into them.
2

Here is one option -- add a second project to your solution.

The first project would be an implementation of the non-COM visible DLL.

The second project would reference the first, and contains a class which is derived from your first class (which implements the COM methods you want to expose). Since the first class already implements all of your COM-exposed interface elements, you just have to declare the second class as implementing the first one, like so:

namespace ClassLibrary2
{
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    [Guid("BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB")]
    public interface MyCOMInterface
    {
        void MyMethod();
    }

    [ComVisible(true)]
    [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
    [ClassInterface(ClassInterfaceType.None)]
    public class Class2 : ClassLibrary1.Class1, MyCOMInterface
    {
        //No implementation is needed here because we're
        //just exposing Class1's methods to COM.
    }
}

By adding a second project, your solution can generate both DLLs in one build.

Just as an aside: you can reference a COM exposed .NET DLL, just as you would any other. That is to say, other .NET projects don't care whether a DLL's methods are exposed to COM-- they can still use all of the DLL's public methods. Using the same DLL, you can export some methods as COM, and have some of them relegated to .NET use only.

I mention this, because you didn't specify the reason behind this architecture.

10 Comments

So, this doesn't have a Main as its not runnable, Its simply a utility library that would also be nice to utilize in some facets of our testing. Would that mean I would then have to implement an interface for each implemented class I needed?
I know, that's why I used the word "main" in quotes. When I say your "main" class, I meant the one that implements your COM interface methods.
@Rig changed the wording, so hopefully it makes more sense to you now.
Thank you for clarifying. I'll see if I have time to try this out today.
...Option (2): if you can p/invoke in Ruby, it's probably possible to host the .NET runtime directly in Ruby, thereby allowing you to call .NET assemblies from Ruby. This is a VBA example of hosting the 2.0 runtime (CorRuntimeHost does not work with 4.0). There is a way to host 4.0+ runtime also, but since it's not possible in VBA, I have not done it. This is an example in C++. Here is some MS docs on it.
|

Your Answer

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