Search code examples
vb.netvisual-studiodlloffice-interopclass-library

Class name in a Library being mangled when calling functions in Word Interop


I'm having some weird trouble with a class library in my application. We have dozens of ComVisible classes and recently I've found a situation where the name of a certain class being exposed through COM is no longer coming across as it used to.

I was able to duplicate the issue in a small sample program, and the issue is related to a single line involved in Microsoft Word Interop. Specifically I have a class Window. Normally this class is ComVisible as 'Window', but if I reference the Document.ActiveWindow property in Word Interop my class becomes ComVisible as 'TestLibrary_Window'. In my real application I have 100s of places where I refer to Window, and I don't want to change them all to TestLibrary_Window, and moreso I want to understand what could possibly be going on by refering to one property changing how my library exposes itself.

I can easily demonstrate the result by looking at the TLB file using a program OleWoo (http://www.benf.org/other/olewoo/). Notice that in the Result 1 you see an entry for coclass Window, but in Result 2 you see an entry for coclass TestLibrary_Window. Result 1 is how I expect the TLB to come across and if the trouble line in my code is commented this is what I receive. Result 2 is what I get when I uncomment the trouble line.

The following is a minimal implementation that duplicates my issue. If the commented line in TestClass is left commented than I have no issue, however if I uncomment that line I have a problem. Note that in my sample code I don't need any code within the Window class to demonstrate the issue.

File 1: TestClass.vb

Imports System.Runtime.InteropServices

<ComVisible(True)>
Public Class TestClass
    Public Sub testFunction()
        Dim oWord As Microsoft.Office.Interop.Word.Application = CreateObject("Word.Application")
        Dim oDoc As Microsoft.Office.Interop.Word.Document = oWord.Documents.Open("c:\temp\test.docx")

        'trouble line
        'oDoc.ActiveWindow.View.TableGridlines = True

        oDoc.Save()
    End Sub

End Class

File 2: Window.vb

Imports System.Runtime.InteropServices

<ComVisible(True)>
Public Class Window

End Class

Result 1: Proper TLB

// Generated .IDL file (by OleWoo)
[
  uuid(b2effb21-a565-4092-bc8f-b92aa429952a),
  version(1.0),
  custom(90883f05-3d28-11d2-8f17-00a0c9a6186d, "TestLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=974b55dd4adecdf1")
]
library TestLibrary
{
    // Forward declare all types defined in this typelib
    dispinterface _TestClass
    interface _TestClass
    dispinterface _Window
    interface _Window
    [
      uuid(eb22957e-07c0-34b2-b813-48d0e9376d35)
    ]
    coclass TestClass {
        [default] interface _TestClass#i;
        interface _Object#i;
    };

    [
      uuid(2266afaa-2145-3508-bb4b-9f8579112b14)
    ]
    coclass Window {
        [default] interface _Window#i;
        interface _Object#i;
    };

    [
      uuid(a13ff8b0-ac7c-33e5-b0f3-5366304512ac),
      hidden,
      dual,
      oleautomation
    ]
    interface _TestClass : IDispatch#i {

    };

    [
      uuid(b81f8ed9-9e71-3248-b3a9-b7a104b3a597),
      hidden,
      dual,
      oleautomation
    ]
    interface _Window : IDispatch#i {

    };

};

Result 2: Bad TLB file

// Generated .IDL file (by OleWoo)
[
  uuid(b2effb21-a565-4092-bc8f-b92aa429952a),
  version(1.0),
  custom(90883f05-3d28-11d2-8f17-00a0c9a6186d, "TestLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=974b55dd4adecdf1")
]
library TestLibrary
{
    // Forward declare all types defined in this typelib
    dispinterface _TestClass
    interface _TestClass
    dispinterface _TestLibrary_Window
    interface _TestLibrary_Window
    [
      uuid(eb22957e-07c0-34b2-b813-48d0e9376d35)
    ]
    coclass TestClass {
        [default] interface _TestClass#i;
        interface _Object#i;
    };

    [
      uuid(2266afaa-2145-3508-bb4b-9f8579112b14)
    ]
    coclass TestLibrary_Window {
        [default] interface _TestLibrary_Window#i;
        interface _Object#i;
    };

    [
      uuid(a13ff8b0-ac7c-33e5-b0f3-5366304512ac),
      hidden,
      dual,
      oleautomation
    ]
    interface _TestClass : IDispatch#i {

    };

    [
      uuid(b81f8ed9-9e71-3248-b3a9-b7a104b3a597),
      hidden,
      dual,
      oleautomation
    ]
    interface _TestLibrary_Window : IDispatch#i {

    };

};

Solution

  • As @TnTinMn mentioned in a comment above, the issue I was having was indeed related to the 'Embed Interop Types' on the reference to Microsoft.Office.Interop.Word. By switching this option to false my TLB is now being created as expected.