Search code examples
visual-c++comxmlhttprequestatlidl

Error registering COM server when interface derives from IXMLHttpRequest


We've created our own implementation of IXMLHttpRequest in a COM server (.exe) like so:

interface IMyXMLHttpRequest : IXMLHttpRequest {
    ...
};

coclass MyXMLHttpRequest {
    [default] interface IMyXMLHttpRequest;
};

The problem is that when the build tries to register the COM server, we get the error "Error accessing the OLE registry". I debugged the registration code and it is failing in RegisterTypeLib. It looks like it is trying to pull in some of the type information relating to IXMLHttpRequest and (guessing here) can't change some registry keys related to that interface.

Is it just plain wrong to derive from IXMLHttpRequest? Should we be deriving from IDispatch instead and making our class use a dual interface? Or is it possible to derive from IXMLHttpRequest and we're just doing it wrong?

Update: I've uploaded a reproducible test case. I simply generated an ATL COM server using the Visual Studio wizard, and then I created a new interface derived from IXMLHttpRequest and a coclass that implements it. The registration fails as I described. If I change the interface to derive from IDispatch then it works fine. 100% reproducible on Windows 7 using Visual Studio 2010, running with elevated privileges.


Solution

  • error MSB3073: :VCEnd" exited with code -2147319780.

    Just for the record, the error is 0x8002801C TYPE_E_REGISTRYACCESS "Error accessing the OLE registry."

    As you already identified, the problem is around inheriting from IXMLHttpRequest interface which is defined outside of the type library. Extending an interface through inheritance is basically not a good idea in first place. Yes it is possible and it makes sense, however as soon as you approach putting this into a type library and having external references, you might be starting hitting weird issues.

    As soon as you referenced IXMLHttpRequest, MIDL compiler is trying to put it into your type library as well. You can witness this by looking into intermediate build files:

    An unexpected copy of IXMLHttpRequest

    It is not what you wanted, is it? You just wanted to reference it because it is already defined and hosted by another type library in msxml6.dll file in system32 (syswow64) directory.

    The main question is why you want to inherit from IXMLHTTPRequest. Why you think a "normal" separate new IDispatch-derived interface is not good enough here? You can still implement IXMLHTTPRequest on this COM class as well. And you would not get into this trouble in first place then.

    Anyway, the building problem is that on IDL the compiler sees definition of IXMLHTTPRequest coming from Windows SDK file directly.

    You want to change your IDL file as follows:

    import "oaidl.idl";
    //import "ocidl.idl"; // <<--- Make direct IXMLHTTPRequest definition invisible
    
    [
        uuid(7397D60F-A428-42C5-B698-9FA850638074),
        version(1.0),
    ]
    library COMServerTestLib
    {
        importlib("stdole2.tlb");
        importlib("msxml6.dll"); // <<--- Reference MSXML type library to import the right interface
    

    In your C++ file you want to make the interface visible for C++ code:

    #include "stdafx.h"
    #include "resource.h"
    #include <msxml6.h> // <<--- Re-add IXMLHTTPRequest definition for C++ code
    #include "COMServerTest_i.h"
    

    Your project is buildable again from here.