Calling COM object from STA thread cause TYPE_E_LIBNOTREGISTERED on some machines

3

I am developing Word shared add-in, using COM shim wizard. http://blogs.msdn.com/b/mshneer/archive/2010/03/19/com-shim-wizards-for-vs-2010.aspx

Everything worked fine until I tried to use some threads. It fail on some machines with TYPE_E_LIBNOTREGISTERED exception for COM-object created in main thread.

I have a Word document object (_doc) from some Word event and try to use from STA thread like this:

Word.Document _doc;
void Start()
{
    _mainLoopThread = new Thread(MainLoop);
    _mainLoopThread.SetApartmentState(ApartmentState.STA);
    _mainLoopThread.IsBackground = true;
    _mainLoopThread.Start();
}
void MainLoop()
{
    // some code...
    Word.Range r = _doc.StoryRanges[Word.WdStoryType.wdMainTextStory];
    // some code...
}

Everything works fine on my dev machine, on test machine and for most of users. However for some user it fails with exception: Unable to cast COM object of type 'Microsoft.Office.Interop.Word.DocumentClass' to interface type 'Microsoft.Office.Interop.Word._Document'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{0002096B-0000-0000-C000-000000000046}' failed due to the following error: Library not registered. (Exception from HRESULT: 0x8002801D (TYPE_E_LIBNOTREGISTERED)).

The only way we were able to reproduce it - is to install Office 2013, then remove it and install Office 2007. I checked registry, but didn't found any registration problems for this guid. I tried tool from MS, that should clear leftovers from Office 2013, http://support.microsoft.com/kb/2739501 but it didn't help.

This is not registration problem, because I can use same _doc object from main thread without any errors. In rgs-file for COM-shim I use STA model InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' } I also set CLR mode as STA in Properties-Linker-Advanced, but this didn't help.

I tried to use CoMarshalInterThreadInterfaceInStream, as suggested here Cannot call COM object created from STAThread from oher STA threads but failed to make it work even on my dev machine. Here is the code: [DllImport("ole32.dll")] static extern int CoMarshalInterThreadInterfaceInStream([In] ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] object pUnk, out IStream ppStm);

    IStream _docForThreadStream = null;

    Guid _docInterfaceGuid;

    void InitDocForThread()
    {            
        object[] attr = _doc.GetType().GetCustomAttributes(typeof(GuidAttribute), false);
        GuidAttribute g = (GuidAttribute)attr[0];
        _docInterfaceGuid = new Guid(g.Value);

        CoMarshalInterThreadInterfaceInStream(ref _docInterfaceGuid, Marshal.GetIUnknownForObject(_doc), out _docForThreadStream);
    }

    [DllImport("ole32.dll")]
    static extern int CoGetInterfaceAndReleaseStream(IStream pStm, [In] ref Guid riid, out object ppv);

    Word.Document _docForThread = null;

    void MainLoop()
    {
            object pDoc;
            int hr = CoGetInterfaceAndReleaseStream(_docForThreadStream, ref _docInterfaceGuid, out pDoc);
            // _docForThreadStream != null, hr == E_NOINTERFACE
     }

CoGetInterfaceAndReleaseStream gives me E_NOINTERFACE when I try to get object from IStream. Can anyone send me link with working example for C#? I googled, but found only some examples for C++.

It seems that Office COM registration get coorrupted such a way that it works for same thread (add-in running in same thread as office), but fails to get marshalled to another STA thread...

c#
multithreading
com
add-in
office-interop
asked on Stack Overflow Dec 5, 2012 by Sergey Belikov • edited May 23, 2017 by Community

1 Answer

-1

Just recently, we watched the very same case: TYPE_E_LIBNOTREGISTERED when making calls to the Word object model in a thread. You must use any Office object model in the main thread only. Please find some info and further links at http://www.add-in-express.com/creating-addins-blog/2010/11/04/threads-managed-office-extensions/.


User contributions licensed under CC BY-SA 3.0