Надстройки VSTO, COMAddIns и RequestComAddInAutomationService [дубликаты]

Пожалуйста, смотрите 1-е редактирование (скриншот внизу):

Я следил за этой статьей, чтобы приложение Winform запускало метод надстройки VSTO: http://blogs.msdn.com/b/andreww/archive/2007/01/15/vsto-add-ins-comaddins-and-requestcomaddinautomationservice.aspx

В конце вышеупомянутой статьи автор упоминает проблему и пытается решить ее здесь: http://blogs.msdn.com/b/andreww/archive/2008/08/11/why-your-comaddin-object-should-derive-from-standardolemarshalobject.aspx

Я просмотрел код несколько раз, и метод получения StandardOleMarshalObject для улучшения исключения не работает!

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

Вот реплика - оба проекта нацелены на .Net 3.5:

а) Создайте новый Office > 2007 или 2010 > Надстройка Excel:

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)
        {
        }
}
}

б) Добавьте класс в надстройку Excel:

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) Задайте «Свойства проекта» > «Сборка» > выберите «Зарегистрировать для COM-взаимодействия». Скомпилируйте надстройку.

d) Новое приложение Winform, ссылка на ExcelAddIn1, Microsoft.Office.Interop.Excel и Office и включение этого кода в 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) Запустите приложение Winform, и строка utils = (IAddinUtilities)addin.Object; завершится ошибкой независимо от того, является ли AddinUtilities производным от StandardOleMarshalObject.

Я в недоумении, поскольку в блоге MSDN конкретно говорится: «Чтобы все это исправить, вы можете просто получить класс AddinUtilities из StandardOleMarshalObject и перестроить:»

1-е ИЗМЕНЕНИЕ: я попробовал код на другом компьютере PC-B, и он работает без производных от StandardOleMarshalObject,

введите здесь описание изображения

Когда я попробовал использовать StandardOleMarshalObject на ПК-В, у меня возникла та же проблема, что и на ПК-А. PC-A не работает ни с тем, ни с другим, и единственная разница, о которой я могу думать, это права администратора.

введите здесь описание изображения

Права администратора и пред-Win7 (старые статьи msdn) - единственные причины, по которым я могу придумать, почему это не сработает.


person Jeremy Thompson    schedule 04.06.2012    source источник