在應用程式層級增益集中呼叫其他 Office 方案的程式碼

更新:2010 年 9 月

您可以將增益集中的物件公開給其他方案 (包括其他 Microsoft Office 方案)。 如果您想要讓其他方案也能使用增益集提供的服務,這就很有用。 例如,如果您的 Microsoft Office Excel 增益集會計算 Web 服務的財務資料,則其他方案可以在執行階段呼叫這個 Excel 增益集來執行這些計算。

**適用於:**本主題中的資訊適用於 Microsoft Office 2010 和 2007 Microsoft Office system 的應用程式層級專案。 如需詳細資訊,請參閱依 Office 應用程式和專案類型提供的功能

這項程序中有兩個主要步驟:

  • 在增益集中,將物件公開給其他方案。

  • 在其他方案中,存取增益集所公開的物件,並呼叫該物件的成員。

可以呼叫增益集程式碼的方案類型

您可以將增益集中的物件公開給下列類型的方案:

  • 在與增益集相同的應用程式處理序中載入之文件內的 Visual Basic for Applications (VBA) 程式碼。

  • 在與增益集相同的應用程式處理序中載入的文件層級自訂。

  • 其他以 Visual Studio 中的 Office 專案範本建立的增益集。

  • COM 增益集 (即直接實作 IDTExtensibility2 介面的增益集)。

  • 任何在與增益集不同的處理序中執行的方案,這類方案也稱為「跨處理序用戶端」(Out-Of-Process Client)。 這包括將 Office 應用程式自動化的應用程式 (例如 Windows Forms 或主控台應用程式),以及在不同處理序中載入的增益集。

將物件公開給其他方案

若要將您增益集中的物件公開給其他方案,請在增益集中執行下列步驟:

  1. 定義想要公開給其他方案的類別。

  2. 覆寫 ThisAddIn 類別的 RequestComAddInAutomationService 方法。 傳回您要向其他方案公開之類別的執行個體。

定義想要公開給其他方案的類別

您想要公開的類別至少必須是公用的、其 ComVisibleAttribute 屬性必須設為 true,而且必須公開 IDispatch 介面。

公開 IDispatch 介面的建議方法是執行下列步驟:

  1. 定義介面,這個介面宣告您要公開給其他方案的成員。 您可以在增益集專案中定義這個介面。 不過,如果您想要將類別公開給非 VBA 方案,可以在個別的類別庫專案中定義這個介面,讓呼叫您增益集的方案不需參考您的增益集專案,就可以參考這個介面。

  2. ComVisibleAttribute 屬性套用至這個介面,並將此屬性設為 true。

  3. 修改您的類別以實作這個介面。

  4. ClassInterfaceAttribute 屬性套用至您的類別,並將這個屬性設為 ClassInterfaceType 列舉的 None 值。

  5. 如果要將類別公開給跨處理序的用戶端,您可能還必須執行下列作業:

    • StandardOleMarshalObject 衍生類別。 如需詳細資訊,請參閱將類別公開給跨處理序的用戶端。

    • 在您定義介面的專案中設定 [註冊 COM Interop] 屬性。 只有在您想要讓用戶端使用早期繫結來呼叫增益集時,才需要執行此作業。 如需詳細資訊,請參閱 HOW TO:註冊 COM Interop 元件

下列程式碼範例示範 AddInUtilities 類別,該類別具有其他方案可以呼叫的 ImportData 方法。 若要在完整的逐步解說內容中查看這個程式碼,請參閱逐步解說:在應用程式層級增益集中呼叫 VBA 的程式碼

<ComVisible(True)> _
Public Interface IAddInUtilities
    Sub ImportData()
End Interface

<ComVisible(True)> _
<ClassInterface(ClassInterfaceType.None)> _
Public Class AddInUtilities
    Implements IAddInUtilities

    ' This method tries to write a string to cell A1 in the active worksheet.
    Public Sub ImportData() Implements IAddInUtilities.ImportData

        Dim activeWorksheet As Excel.Worksheet = Globals.ThisAddIn.Application.ActiveSheet

        If activeWorksheet IsNot Nothing Then
            Dim range1 As Excel.Range = activeWorksheet.Range("A1")
            range1.Value2 = "This is my data"
        End If
    End Sub
End Class
[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 屬性設定為 ClassInterfaceType 列舉的 AutoDispatchAutoDual 值。 如果您這麼做,即不需要專門定義一個介面來宣告方法。 不過,VBA 程式碼可以呼叫您類別中的任何公用和非靜態方法,包括取自基底類別 (如 Object) 的方法。 此外,使用早期繫結的跨處理序用戶端不能呼叫您的類別。

將類別公開給跨處理序的用戶端

如果您想要將增益集中的類別公開給跨處理序的用戶端,您應該從 StandardOleMarshalObject 衍生此類別,以確保跨處理序的用戶端可以呼叫您所公開的增益集物件。 否則,當嘗試在跨處理序用戶端中取得所公開物件的執行個體時,可能會意外失敗。

這是因為所有對 Office 應用程式物件模型的呼叫都必須在主要 UI 執行緒中進行,但是跨處理序用戶端會在任意 RPC (遠端程序呼叫) 執行緒中執行對您物件的呼叫。 .NET Framework 中的 COM 封送處理機制並不會切換執行緒,而是會嘗試在連入 RPC 執行緒 (而不是主要 UI 執行緒) 上封送處理對您物件的呼叫。 如果您的物件是衍生自 StandardOleMarshalObject 之類別的執行個體,則對您物件的傳入呼叫會自動封送處理至當初用以建立所公開物件的執行緒,而該執行緒會成為主應用程式的主要 UI 執行緒。

如需在 Office 方案中使用執行緒的詳細資訊,請參閱 Office 中的執行緒支援

覆寫 RequestComAddInAutomationService 方法

下列程式碼範例示範如何在您的增益集中覆寫 ThisAddIn 類別中的 RequestComAddInAutomationService。 這個範例假設您已經定義想要公開給其他方案,且名稱為 AddInUtilities 的類別。 若要在完整的逐步解說內容中查看這個程式碼,請參閱逐步解說:在應用程式層級增益集中呼叫 VBA 的程式碼

Private utilities As AddInUtilities

Protected Overrides Function RequestComAddInAutomationService() As Object
    If utilities Is Nothing Then
        utilities = New AddInUtilities()
    End If
    Return utilities
End Function
private AddInUtilities utilities;

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

    return utilities;
}

載入增益集時,Visual Studio Tools for Office Runtime 會呼叫 RequestComAddInAutomationService 方法。 執行階段會將傳回的物件指派給代表增益集之 COMAddIn 物件的 Object 屬性。 這個 COMAddIn 物件可供其他 Office 方案以及將 Office 自動化的方案使用。

從其他方案存取物件

若要呼叫您增益集中的已公開物件,請在用戶端方案中執行下列步驟:

  1. 取得代表公開之增益集的 COMAddIn 物件。 用戶端可以使用主 Office 應用程式的物件模型中的 Application.COMAddIns 屬性,存取所有可用的增益集。

  2. 存取 COMAddIn 物件的 Object 屬性。 這個屬性會傳回增益集中的已公開物件。

  3. 呼叫已公開之物件的成員。

對於 VBA 用戶端和非 VBA 用戶端,您使用 COMAddIn.Object 屬性之傳回值的方式會不同。 對於跨處理序用戶端,還需要其他程式碼才能避免可能的競爭條件。

從 VBA 方案存取物件

下列程式碼範例示範如何使用 VBA 呼叫增益集所公開的方法。 這個 VBA 巨集會呼叫 ExcelImportData 增益集中定義的 ImportData 方法。 若要在完整的逐步解說內容中查看這個程式碼,請參閱逐步解說:在應用程式層級增益集中呼叫 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 屬性值轉型為方案所實作的介面,然後才能在介面物件上呼叫已公開方法。 下列程式碼範例示範如何從使用 Visual Studio 中的 Office 開發人員工具建立的不同增益集中呼叫 ImportData 方法。

Dim addIn As Office.COMAddIn = Globals.ThisAddIn.Application.COMAddIns.Item("ExcelImportData")
Dim utilities As ExcelImportData.IAddInUtilities = TryCast( _
    addIn.Object, ExcelImportData.IAddInUtilities)
utilities.ImportData()
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

請參閱

工作

逐步解說:在應用程式層級增益集中呼叫 VBA 的程式碼

HOW TO:在 Visual Studio 中建立 Office 專案

概念

使用擴充性介面自訂 UI 功能

應用程式層級增益集的架構

其他資源

應用程式層級增益集程式設計

開發 Office 方案

變更記錄

日期

記錄

原因

2010 年 9 月

改善內容的組織編排並移除多餘資訊。

資訊加強。