Поделиться через


Код вызова надстроек VSTO из других решений Office

Объект в надстройке VSTO можно предоставить другим решениям, включая другие решения Microsoft Office. Это полезно, если надстройка VSTO предоставляет службу, доступ к которой нужно предоставить другим решениям. Например, если у вас есть надстройка VSTO для Microsoft Office Excel, которая выполняет вычисления по финансовым данным из веб-службы, другие решения могут выполнять эти вычисления, вызывая надстройку VSTO Excel во время выполнения.

Область применения. Сведения в этом разделе относятся к проектам надстроек VSTO. Дополнительные сведения см. в разделе "Функции", доступные по Приложение Office ликации и типу проекта.

Этот процесс включает два основных этапа.

  • В надстройке VSTO предоставьте доступ к объекту другим решениям.

  • В другом решении обратитесь к объекту, предоставленному надстройкой VSTO, и вызовите члены объекта.

Типы решений, которые могут вызывать код в надстройке

Объект в надстройке VSTO можно предоставить следующим типам решений:

  • код Visual Basic для приложений (VBA) в документе, который загружается в тот же процесс приложения, что и надстройка VSTO;

  • настройки уровня документа, которые загружаются в тот же процесс приложения, что и надстройка VSTO;

  • другие надстройки VSTO, созданные с помощью шаблонов проектов Office в Visual Studio;

  • надстройки VSTO COM (то есть надстройки VSTO, реализующие интерфейс IDTExtensibility2 напрямую);

  • любые решения, выполняющиеся в процессе, который отличается от процесса надстройки VSTO (эти типы решений также называют внепроцессными клиентами). К ним относятся приложения, автоматизирующие работу приложений Office, такие как Windows Forms или консольное приложение, а также надстройки VSTO, загружаемые в другой процесс.

Предоставление объектов другим решениям

Чтобы предоставить доступ к объекту в надстройке VSTO другим решениям, выполните в надстройке VSTO указанные ниже действия.

  1. Определите класс, которые требуется предоставлять другим решениям.

  2. Переопределите метод RequestComAddInAutomationService в классе ThisAddIn . Верните экземпляр класса, который требуется предоставлять другим решениям.

Определение класса, который требуется предоставить другим решениям

Как минимум, предоставляемый класс должен быть общим, для атрибута этого класса ComVisibleAttribute должно быть задано значение trueи он должен предоставлять интерфейс IDispatch .

Предоставление интерфейса IDispatch рекомендуется выполнять следующим образом.

  1. Определите интерфейс, объявляющий члены, которые требуется предоставить другим решениям. Этот интерфейс можно определить в проекте надстройки VSTO. Однако может потребоваться определить его в отдельном проекте библиотеки класса, если класс потребуется предоставлять решениям, не основанным на VBA. Это позволит решениям, вызывающим вашу надстройку VSTO, ссылаться на интерфейс, не ссылаясь на проект надстройки VSTO.

  2. Примените атрибут ComVisibleAttribute к этому интерфейсу и задайте для него значение true.

  3. Измените класс для реализации этого интерфейса.

  4. Примените ClassInterfaceAttribute атрибут к классу и задайте для этого атрибута значение None перечисления ClassInterfaceType .

  5. Если вы хотите предоставить этому классу внепроцессные клиенты, вам также может потребоваться выполнить следующие действия.

    • Создайте класс, производный от StandardOleMarshalObject. Дополнительные сведения см. в разделе "Предоставление классов внепроцессным клиентам".

    • Задайте свойство Регистрация для COM-взаимодействия в проекте, в которым вы определили интерфейс. Это свойство необходимо только в том случае, если клиенты могут использовать раннюю привязку для вызова надстройки VSTO.

    Следующие примеры кода демонстрируют класс AddInUtilities с методом ImportData , который может вызываться другими решениями. Чтобы просмотреть этот код в контексте более крупного пошагового руководства, см . пошаговое руководство. Пошаговое руководство. Вызов кода в надстройке VSTO из VBA.

    [ComVisible(true)]
    public interface IAddInUtilities
    {
        void ImportData();
    }
    
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class AddInUtilities : IAddInUtilities
    {
        // This method tries to write a string to cell A1 in the active worksheet.
        public void ImportData()
        {
            Excel.Worksheet activeWorksheet = Globals.ThisAddIn.Application.ActiveSheet as Excel.Worksheet;
    
            if (activeWorksheet != null)
            {
                Excel.Range range1 = activeWorksheet.get_Range("A1", System.Type.Missing);
                range1.Value2 = "This is my data";
            }
        }
    }
    

Предоставление классов VBA

Если вы выполните приведенные выше действия, код VBA сможет вызывать только те методы, которые будут объявлены в интерфейсе. Код VBA не может вызывать остальные методы в классе, включая методы, получаемые классом из базовых классов, таких как Object.

Кроме того, можно предоставить интерфейс IDispatch, задав ClassInterfaceAttribute атрибут для значения AutoDispatch или AutoDual перечисленияClassInterfaceType. Если вы предоставляете интерфейс, вам не нужно объявлять методы в отдельном интерфейсе. Тем не менее код VBA сможет вызывать все общие и нестатические методы в классе, включая полученные из базовых классов, таких как Object. Кроме того, внепроцессные клиенты, использующие раннее связывание, не смогут вызывать ваш класс.

Предоставление классов внепроцессным клиентам

Чтобы предоставить класс в надстройке VSTO внепроцессным клиентам, необходимо создать класс, производный от StandardOleMarshalObject . Это гарантирует, что внепроцессные клиенты смогут вызывать предоставленный объект надстройки VSTO. В противном случае попытки получить экземпляр предоставленного объекта во внепроцессном клиенте может завершиться неожиданным сбоем.

Это происходит из-за того, что все вызовы объектной модели Приложение Office ликации должны выполняться в основном потоке пользовательского интерфейса, но вызовы из внепроцессного клиента к объекту будут поступать в произвольный поток RPC (удаленный вызов процедуры). Механизм маршалинга COM в .NET Framework не переключает потоки и вместо этого попытается выполнить маршалинг вызова в объект для входящего потока RPC вместо основного потока пользовательского интерфейса. Если объект является экземпляром класса, производного от StandardOleMarshalObject, для входящих вызовов вашего объекта автоматически выполняется маршалинг в поток, в котором был создан предоставляемый объект (то есть в основной поток пользовательского интерфейса ведущего приложения).

Дополнительные сведения об использовании потоков в решениях Office см. в разделе "Поддержка потоков" в Office.

Переопределите метод RequestComAddInAutomationService

Следующий пример кода демонстрирует переопределение метода RequestComAddInAutomationService в классе ThisAddIn в надстройке VSTO. В примере предполагается, что вы определили класс с именем AddInUtilities , который требуется предоставить другим решениям. Чтобы просмотреть этот код в контексте более крупного пошагового руководства, см . пошаговое руководство. Пошаговое руководство. Вызов кода в надстройке VSTO из VBA.

private AddInUtilities utilities;

protected override object RequestComAddInAutomationService()
{
    if (utilities == null)
        utilities = new AddInUtilities();

    return utilities;
}

При загрузке надстройки VSTO среда выполнения набор средств Visual Studio для Office вызывает RequestComAddInAutomationService метод. Среда выполнения назначает возвращенный объект свойству COMAddIn COMAddIn.Object объекта, представляющего надстройку VSTO. Этот объект COMAddIn доступен для других решений Office, а также для решений, отвечающих за автоматизацию Office.

Доступ к объектам из других решений

Чтобы вызвать предоставляемый объект в вашей надстройке VSTO, выполните в клиентском решении указанные ниже действия.

  1. Получите объект COMAddIn , представляющий предоставляемую надстройку VSTO. Клиенты могут получать доступ ко всем доступным надстройкам VSTO, используя свойство Application.COMAddIns в объектной модели ведущего приложения Office.

  2. Доступ к свойству COMAddIn COMAddIn.Object объекта. Это свойство возвращает предоставленный объект из надстройки VSTO.

  3. Вызовите члены предоставляемого объекта.

    Способ использования возвращаемого значения свойства COMAddIn.Object отличается для клиентов VBA и клиентов, отличных от VBA. Для внепроцессных клиентов требуется дополнительный код, который позволит избежать возникновения состояния гонки.

Доступ к объектам из решений VBA

В следующем примере кода показано, как использовать VBA для вызова метода, предоставляемого надстройкой VSTO. Этот макрос VBA вызывает метод с именем ImportData , определенный в надстройке VSTO с именем ExcelImportData. Чтобы просмотреть этот код в контексте более крупного пошагового руководства, см . пошаговое руководство. Пошаговое руководство. Вызов кода в надстройке VSTO из VBA.

Sub CallVSTOMethod()
    Dim addIn As COMAddIn
    Dim automationObject As Object
    Set addIn = Application.COMAddIns("ExcelImportData")
    Set automationObject = addIn.Object
    automationObject.ImportData
End Sub

Доступ к объектам из решений, отличных от VBA

В решении, отличном от VBA, необходимо привести значение свойства COMAddIn.Object к интерфейсу, который он реализует, а затем вызвать предоставленные методы в объекте интерфейса. В следующем примере кода показано, как вызвать метод ImportData из другой надстройки VSTO, которая была создана с помощью набора Office Developer Tools в Visual Studio.

object addInName = "ExcelImportData";
Office.COMAddIn addIn = Globals.ThisAddIn.Application.COMAddIns.Item(ref addInName);
ExcelImportData.IAddInUtilities utilities = (ExcelImportData.IAddInUtilities)addIn.Object;
utilities.ImportData();

В этом примере при попытке приведения значения свойства COMAddIn.Object к AddInUtilities классу, а не IAddInUtilities интерфейса, код вызовет InvalidCastExceptionисключение.