COR_E_INVALIDOLEVARIANTTYPE

I am working on developing a VS.NET addin. In that context, I'm hosting the MS web browser control to provide some of the user interface for the addin. In order to respond to user events from inside the HTML document, I'm hosting the control as described in the second example here: http://www.codeproject.com/books/0764549146_8.asp

I'm implementing various OLE interfaces on the site that is hosting the control(through IOleObject.SetClientSite), including IDocHostUIHandler. In the IDocHostUIHandler.GetExternal method I'm providing an IDispatch object that looks something like this:

public interface IFunkyStuff : IDispatch
{
  void ShowMessageBox();
}

public class FunkyStuff : IFunkyStuff
{
  public void ShowMessageBox()
  {
    System.Windows.Forms.MessageBox.Show( "Hi there" );
  }
}


I'm calling the ShowMessageBox method from a link in the HTML document loaded into the web browser:

<a href='BLOCKED SCRIPT external.ShowMessageBox()'>Click me</a>

Now, the strange thing is, if IFunkyStuff/FunkyStuff is implemented in the main addin dll, Ankh.dll, which is registered for COM interop, I get the following messagebox upon clicking the link:

---------------------------
Error
---------------------------
A Runtime Error has occurred.
Do you wish to Debug

Line: 0
Error: Could not complete the operation due to error 80131531.
---------------------------
Yes   No
---------------------------

0x80131531 is the HRESULT COR_E_INVALIDOLEVARIANTTYPE(which corresponds to a InvalidOLEVariantTypeException - "The exception thrown by the marshaler when it encounters an argument of a variant type that can not be marshaled to
managed code."

If I put the interface and the coclass in a separate assembly, everything works just fine and the messagebox appears when I click the link. However, I'd rather not do that for various reasons.

Is there any way I can put the interface and the coclass in the main addin dll Why is this happening in the first place



Answer this question

COR_E_INVALIDOLEVARIANTTYPE

  • HitchB52

    BTW - all my OLE interfaces can be found here (without the changes you suggested - I haven't checked in those yet): http://ankhsvn.com/svn/finalproject/trunk/src/Utils/Ole/
  • Anonym0us

    Hi Arild,

    could I get a stack trace of when you get the InvalidOLEVariantTypeException   When you debug, go to Debug | exceptions | Common Language Runtime Exceptions | System.Runtime.InteropServices | System.Runtime.InteropServices.InvalidOleVariantTypeException, mark the option to Break into the debugger.  Make sure we use a debug build of the add-in assembly.


    thanks!
    Mike

  • imatureStudent

    There is no separate IE process in this case. I am using the web browser component in-proc in the VS.NET process itself. I have a debugger attached to VS.NET, and the debugger does not break when this happens.
  • Creanlin

    Yes, IDocHostUIHandler::GetExternal definitely does get hit, and the message box pops up after returning.

    GetExternal used to look like this:


    void GetExternal([MarshalAs(UnmanagedType.IDispatch)] out object ppDispatch);
     


    If I changed it to this:


    void GetExternal([MarshalAs(UnmanagedType.Interface)] out object ppDispatch);
     


    I get another error message - "Class does not support automation."


  • vinceb

    Hi Arild,

    I have implemented an add-in that contains FunkyStuff/IFunkyStuff and uses the IDocHostUIHandler::GetExternal approach.  Please email me at mikewong@microsoft.com if you want to see my sample to compare with your code.  In general, here is my COM object in the add-in

    [System.Runtime.InteropServices.ComVisible(true), Guid("7A26409F-621E-4731-B41B-C5626204D324"), System.Runtime.InteropServices.InterfaceTypeAttribute(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsDual)]

    public interface IFunkyStuff

    {

    [System.Runtime.InteropServices.DispId(1)]

    void ShowMessageBox();

    }

    [ComVisible(true), Guid("9534D07D-B19B-43a7-9ED0-DD0C1044514F")]

    public class FunkyStuff : IFunkyStuff

    {

    public void ShowMessageBox()

    {

    System.Windows.Forms.MessageBox.Show( "Hi there" );

    }

    }

    here is my html

     <script id=clientEventHandlersJS language=javascript>
    <!--

    function Button1_onclick() {
     window.external.ShowMessageBox();
    }

    //-->
    </script>


    </head>
    <body>

    <INPUT id="Button1" type="button" value="Button" name="Button1" language=javascript onclick="return Button1_onclick()">

    </body>

    thanks!
    mike


  • dmgks

     Mike Wong wrote:

    In any case, can you also experiment with returning a simple COM object other than the FunkyStuff object i.e. reference a simple ATL dll and create and instance in GetExternal, and return a IDispatch just to see if it is specific to IFunkyStuff/FunkyStuff.  That might help us narrow down the issue if we find that it is specific to the implementation of FunkyStuff.  It doesn't have to be an ATL object, another simple test would be to create a com object already installed on the system like Scripting.FileSystemObject.

    Well, as I mentioned initially, even FunkyStuff/IFunkyStuff works fine as long as the implementation does not reside in the main addin DLL, Ankh.dll. If I, for instance, put it in Ankh.UI.dll, everything works as expected.

  • Victor I. Dorofeyev

    Hi Arild,

    strange that UnmanagedType.Interface did not work for you.  We use that internally i.e.

    [return: MarshalAs(UnmanagedType.I4)]
                [PreserveSig]
                int GetExternal(
                               [Out, MarshalAs(UnmanagedType.Interface)]
                               out object ppDispatch);

    In any case, can you also experiment with returning a simple COM object other than the FunkyStuff object i.e. reference a simple ATL dll and create and instance in GetExternal, and return a IDispatch just to see if it is specific to IFunkyStuff/FunkyStuff.  That might help us narrow down the issue if we find that it is specific to the implementation of FunkyStuff.  It doesn't have to be an ATL object, another simple test would be to create a com object already installed on the system like Scripting.FileSystemObject.

    thanks!
    mike


  • Justin20009

    Well, the thing here is that the exception doesn't happen anywhere in managed code. What happens is that I click the link (which is supposed to call the  method on the external object) and I get the following dialog:

    http://ankhsvn.com/images/ieerror.png


  • WayneSpangler

    Excellent Arild!

    Glad you got it working now.

    PEBKAC -never heard that one before,  that is new one! :-)

    Thanks!
    mike

  • Dan Ferguson

    Hi Arlind,

    I wonder if this is related to another issue that we have seen in the past.  Could you try a quick test for me

    Are you declaring the interface IOleClientSite   If so, make sure the GetContainer has a [MarshalAs(UnmanagedType.Interface)] on its single parameter.  Default parameter marshaling for objects is variants but the definition calls for an interface (IOleContainer) (thanks ChrisEck)

    I noticed that the GetContainer parameter referenced in codeproject url above defines it as object (variant)

    thanks!
    Mike Wong

  • megatiko

     Mike Wong wrote:
    Hi Arild,

    I have implemented an add-in that contains FunkyStuff/IFunkyStuff and uses the IDocHostUIHandler::GetExternal approach.  Please email me at mikewong@microsoft.com if you want to see my sample to compare with your code. 

    Thanks for the offer, but it seems that won't be necessary now Smile. I just had a major d'oh! moment.

    What I had completely forgotten was that I had applied [assembly:ComVisible(false)] on Ankh.dll. This obviously explains why it worked if I put the interface and coclass in another DLL, but always failed in Ankh.dll

    I discovered this when I copied your IFunkyStuff/FunkyStuff implementation (which included the ComVisible(true) attribute) a verbo and was astonished to see it actually working.

    Sorry to have taken up so much of your time with what eventually turned out to be a PEBKAC Tongue Tied Your help is much appreciated!

  • tomazek

    I tried it, but no dice, I'm afraid. IOleClientSite looks like this now:

    [ComImport,Guid("00000118-0000-0000-C000-000000000046"),InterfaceType(ComInterfaceType.InterfaceIsIUnknown),]
    public interface IOleClientSite{
       void SaveObject();
       void GetMoniker(uint dwAssign, uint dwWhichMoniker, ref object ppmk);
       void GetContainer( [MarshalAs(UnmanagedType.Interface)] ref object ppContainer);
       void ShowObject();
       void OnShowWindow(bool fShow);
       void RequestNewObjectLayout();
    }


  • Brandon Eckert

    Hi Arild,

    when debugging, are you getting into your IDocHostUIHandler::GetExternal method at all   Does the messagebox popup with the error on return to that call   Could you set a breakpoint in your implementation to verify   Specify mixed mode debugging as well.

    If so, could we also apply the attribute we applied earlier to the return of GetExternal  i.e.

    interface IDocHostUIHandler : IUnknown
    {
    ...
    [return: MarshalAs(UnmanagedType.Interface)]
    public object GetExternal();
    ...
    }

    thanks!
    mike

  • Armoghan

    Hi Arild,

    if you attach to the instance of IE, are you breaking in the debugger on any exceptions before you get the dialog you mentioned above  

    thanks!
    mike

  • COR_E_INVALIDOLEVARIANTTYPE