3

Please see 1st Edit (the screenshot at the bottom):

I've followed this article to have a Winform app trigger a VSTO Add-In method: http://blogs.msdn.com/b/andreww/archive/2007/01/15/vsto-add-ins-comaddins-and-requestcomaddinautomationservice.aspx

At the end of the above article the author mentions a issue and tries to ameliorate it here: http://blogs.msdn.com/b/andreww/archive/2008/08/11/why-your-comaddin-object-should-derive-from-standardolemarshalobject.aspx

I have been through the code several times now and the method to derive StandardOleMarshalObject to ameliorate the exception does not work!

System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to interface type ... This operation failed because the QueryInterface call on the COM component for the interface with IID

Here is a repro - both projects target .Net 3.5:

a) Create a new Office > 2007 or 2010 > Excel Add-In:

namespace ExcelAddIn1
{
    public partial class ThisAddIn
    {
        private AddinUtilities addinUtilities;
        protected override object RequestComAddInAutomationService()
        {
            if (addinUtilities == null)
            {
                addinUtilities = new AddinUtilities();
            }
            return addinUtilities;
        }
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
        }
        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }
}
}

b) Add a class to the Excel Add-In:

namespace ExcelAddIn1
{
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IAddinUtilities
{
    void DisplayMessage();
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class AddinUtilities :
    StandardOleMarshalObject,
    IAddinUtilities
{
    void IAddinUtilities.DisplayMessage()
    {
        MessageBox.Show("Hello World");
    }
}
}

c) Set Project Properties > Build > seklect Register For COM Interop. Compile the Add-In.

d) New Winform App, reference the ExcelAddIn1, Microsoft.Office.Interop.Excel and Office and include this code in Form1:

public partial class Form1 : Form
{
private Microsoft.Office.Interop.Excel.Application excel;
private IAddinUtilities utils;
public Form1()
{
    InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
    excel = new Microsoft.Office.Interop.Excel.Application();
    excel.Visible = true;
    excel.Workbooks.Add(Microsoft.Office.Interop.Excel.XlSheetType.xlWorksheet);
    object addinName = "ExcelAddin1";
    COMAddIn addin = excel.COMAddIns.Item(ref addinName);
    utils = (IAddinUtilities)addin.Object;
    utils.DisplayMessage();
}
}

e) Run the Winform app and the line utils = (IAddinUtilities)addin.Object; fails regardless of whether or not AddinUtilities derives from StandardOleMarshalObject.

I am at a loss here as the MSDN Blog specifically says: "To fix all this, you can simply derive the AddinUtilities class from StandardOleMarshalObject, and rebuild:"

1st EDIT: I tried the code on another PC-B and it works without deriving from StandardOleMarshalObject,

enter image description here

When I tried with StandardOleMarshalObject on PC-B I got the same problem as PC-A. PC-A doesn't work with either ways and the only difference I can think of is admin rights.

enter image description here

Admin rights and pre-Win7 (old msdn articles) are the only reasons I can think of why it would not work.

Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321

0 Answers0