1. 程式人生 > >VSTO:使用C#開發Excel、Word【6】

VSTO:使用C#開發Excel、Word【6】

exc 和集 handle helper class a 一切都 mic 必須 ges

Office主互操作程序集(PIA)
在了解如何構建Office解決方案之前,您需要更詳細地了解在.NET中與Office對象模型通信的托管程序集。用於與Office通話的托管程序集稱為Office主互操作程序集(PIA)。

如前所述,當您正在與.NET中的Office對象模型交談時,您可以通過稱為COM互操作的.NET技術與之交談。 Office對象模型全部以公開COM接口的非托管代碼(C和C ++)編寫。要通過托管代碼(C#或Visual Basic)與這些COM接口通話,您可以通過一個包裝器進行通話,允許托管代碼與Office的非托管COM接口進行交互操作。這個包裝器是一組被編譯成一個稱為主互操作程序集或PIA的程序集的.NET類。

描述這些程序集時使用“primary”一詞,因為它們是經Office認可的用於與Office對象模型通信的包裝器。需要這個指定,因為您可以使用.NET提供的工具(稱為TLBIMP)為Office COM對象模型創建自己的包裝器。您自己創建的包裝器稱為互操作程序集(IA),而不是主互操作程序集。即使您可能會嘗試使用TLBIMP並構建自己的互操作程序集,但除了Office提供的互操作程序集之外,您也不應該使用任何其他操作來進行Office開發。如果每個開發人員都為自己的Office開發人員創建了自己的套裝,那麽沒有Office解決方案可以與任何人的解決方案進行互操作;每個interop包裝類,例如每個開發人員創建的Worksheet將被視為一種不同的類型。即使我創建的Interop程序集有一個Worksheet對象,並且您創建的Interop程序集具有一個Worksheet對象,我無法傳遞我的Worksheet對象,也不能傳遞給您的Worksheet對象。我們需要使用相同的互操作程序集:主互操作程序集。

不建立自己的互操作程序集的第二個原因是Office已經對PIA進行了特殊修復,以便在執行Office開發時使它們更好地工作。如果您生成自己的,那麽您很可能遇到在PIA中修復的問題。

安裝PIA
Office 2003 PIA可通過Office 2003安裝程序獲得。 Office 2003 PIA也可以作為Microsoft Windows Installer包提供,您可以使用應用程序重新分發。要通過Office 2003安裝程序安裝Office 2003 PIA,進行安裝時,請在Office 2003安裝向導的第一步中選中“選擇應用程序高級自定義”復選框。然後在向導的下一個屏幕中顯示的樹控件中,您將在每個應用程序下面看到一個可編程控制器可用的.NET可編程性支持節點,如圖1-4所示。單擊每個這些.NET可編程支持節點,並確保您從我的計算機設置運行。此外,在樹中的Office工具節點下,您可能需要啟用Microsoft Forms 2.0 .NET可編程支持和智能標記.NET可編程性支持。獲取Office 2003 PIA的第二種方法是完成Office 2003all的安裝,.NET可編程性支持將自動打開。

技術分享

Office PIA安裝到全局程序集緩存(GAC)。 GAC通常位於Windows目錄的Assembly子目錄中。

有多個Office PIA可用。 表1-4列出了最常見的一些。 這裏列出的一個PIA是Office.dll PIA,它是在Office應用程序(如CommandBar)之間共享的常見類型。

技術分享

參考PIAs
添加對PIA的引用對於大多數VSTO項目是不必要的,因為引用將自動為您添加。 本書中的控制臺應用程序示例,例如自動化Excel的控制臺應用程序示例可以鍵入Visual Studio控制臺項目並編譯,但必須先添加對必要的PIA的引用。 要添加引用,請在Visual Studio解決方案資源管理器中右鍵單擊項目下的“引用”文件夾,如圖1-5所示。 在右鍵單擊“引用”文件夾時,從彈出的菜單中選擇“添加引用”。

技術分享

選擇出現的“添加引用”對話框的COM選項卡,如圖1-6所示。 COM引用按組件名稱列出,與表1-4中的描述列匹配。 因此,要添加對Excel PIA的引用,請選擇Microsoft Excel 11.0對象庫,然後單擊確定按鈕將Excel 2003 PIA參考添加到項目中,如圖1-6所示。

技術分享

請註意圖1-6中“添加引用”對話框的“COM”選項卡中的“路徑”列顯示PIA包裝的COM庫的路徑。例如,Microsoft Excel 11.0 Object Library指向您的計算機上Excel.EXE可執行文件的位置。當您選擇這些引用並關閉對話框時,可以通過擴展項目中的“引用”文件夾,右鍵單擊添加的引用,然後選擇“屬性”,來檢查添加的實際引用的屬性。您將看到Visual Studio計算出GAC中與您選擇的COM對象相對應的PIA托管對象。在這種情況下,您將不會獲得對Excel.EXE可執行文件的引用,而是GAC中的Microsoft.Office.Interop.Excel.dll。

最後,請註意,即使您沒有明確添加對Microsoft Office 11.0 Object Library(office.dll)的引用,也為您添加了一個引用。這是因為Excel 11.0 Object Library使用Microsoft Office 11.0 Object Library中的類型。 Visual Studio檢測到這一點,並自動將所需的Office PIA添加到您的項目引用。

瀏覽PIA
當您看到在Visual Studio中的對象瀏覽器中引用的PIA時,您可能會發現自己很困惑。對象瀏覽器顯示了作為互操作包裝器一部分創建的許多輔助對象。例如,考慮.NET Interop對於看似簡單的Excel Application對象的引用。它變成一個多關聯的頭部引用(8個頭標準引用,36私自引用)。以下所有以下是在瀏覽器中與Excel Application對象相關的公共類型:

Interfaces(接口

  • _Application

  • AppEvents

  • AppEvents_Event

  • Application

  • IAppEvents

Delegates(委托)

  • AppEvents_*EventHandler (29 of them)

Classes(類)

  • AppEvents_SinkHelper (AppEvents)

  • ApplicationClass (_Application, Application, AppEvents_Event)

此圖形針對Chart,OLEObject,QueryTable,Worksheet和Workbook。

我們嘗試通過從Excel Application對象的原始COM定義向後工作來解開這個混亂。 Application對象的COM coclass看起來像thisit有兩個接口,一個稱為_Application的主接口和一個名為AppEvents的事件接口。 您可以將coclass視為定義COM類實現的接口的東西。

coclass Application {
        [default] interface _Application;
        [default, source] dispinterface AppEvents;
    };

TLBIMP(用於處理Excel的COM類型庫並使用PIA)直接導入_Application和AppEvents接口,因此這解釋了八種類型中的兩種來自哪裏。但是AppEvents界面不是很有用,似乎像某種TLBIMP轉換的工件。它必須進一步處理,以創建後面描述的AppEvents_Event的另一個界面。

當TLBIMP處理COM coclass時,它將創建一個名為ApplicationClass的.NET類,它通過獲取coclass名稱並附加Class命名。它還創建一個與名為Application的coclass同名的.NET接口。如果您在瀏覽器中查看應用程序,它沒有屬於自己的屬性和方法,但它來自與coclass相關聯的其他兩個接口:_Application和AppEvents_Event。

我們還沒有解釋AppEvents_Event接口來自哪裏。當TLBIMP處理coclass上的AppEvents事件接口時,它會創建幾個幫助類型。首先,它創建AppEvents_Event,它看起來像AppEvents,但事件和委托類型替換AppEvents中的方法。它還創建名為AppEvents_ * EventHandler的代理,其中*是原始AppEvents界面上每個方法的方法名稱。最後,它創建一個可以忽略的AppEvents_SinkHelper。

這只會使IAppEvents界面無法解釋。 TLBIMP直接導入此接口,因為它是Excel類型庫中的公共類型。你也可以忽略這個。這實際上是AppEvents的重復,除了AppEvents在類型庫中聲明為dispinterface,而IAppEvents被聲明為雙重接口類型。

那麽你真的使用哪些?基本上,你應該只在代碼中使用Application接口(派生自_Application和AppEvents_Events)和代理。你通常可以假裝別人不存在。此規則的一個例外是當方法和事件名稱相沖突,如本章前面所述。要在要連接到事件時要調用該方法或AppEvents_Event接口的方法和事件之間消除歧義,則必須將其轉換為_Application接口。表1-5給出了一個總結。

技術分享

由TLBIMP為coclass創建的應用程序接口以有趣的方式表現。 您可以在C#中編寫代碼,使其看起來像您正在創建應用程序界面的一個實例,我們都知道這是不可能的:

Excel.Application myApp = new Excel.Application();

真的,這是在幕後使用ApplicationClass的語法糖(應用程序界面歸因於將其與ApplicationClass相關聯)來創建一個Excel Application對象並返回相應的接口。

最後,我們前面提到這個模式對於Chart,OLEObject,QueryTable,Worksheet和Workbook都是重復的。 圖表映射是帶ChartEvents的圖表和AppEvent的直接應用程序,您將得到一般的想法。 工作表有點不同 它的coclass看起來像這樣:

coclass Worksheet {
        [default] interface _Worksheet;
        [default, source] dispinterface DocEvents;
    };

所以對於工作表,使用Worksheet替換Application,而是將AppEvents替換為DocEventsyielding DocEvents_ * EventHandler作為WorkSheet事件的代理。

QueryTable甚至是極限。 它的coclass看起來像這樣:

coclass QueryTable {
        [default] dispinterface _QueryTable;
        [default, source] dispinterface RefreshEvents;
    };

所以對於QueryTable,使用QueryTable替換Application,並將AppEvents替換為Refresh Event,從而生成RefreshMents * EventHandler作為QueryTable事件的委托。

Dummy方法

當您在Visual Studio中的對象瀏覽器中查看Excel PIA時,您可能會註意到其中包含文本Dummy的大量方法。甚至有一個名為IDummy的界面。

不,這不是Excel的侮辱你的智慧的方式。一切都是虛擬的,它是一種測試方法,在Microsoft的內部“調試”版本中實際上具有合法目的和更具描述性的名稱。例如,Application.Dummy6在Excel的調試版本中稱為Application.DebugMemory。在Excel的零售版本中,每種方法都重命名為Dummy。這些Dummy方法中的所有508實際上都在調試Excel中做了一些事情,但是在零售版本的Excel中,除了在調用時引發錯誤,它們什麽都不做。

Excel將這些標記為“隱藏”,但C#對象瀏覽器默認顯示隱藏方法。當您在C#對象瀏覽器中查看PIA時,您將看到這些Dummy方法。如果創建Visual Basic項目,Visual Basic對象瀏覽器將隱藏具有此屬性的方法和屬性。

結論
本章介紹了Office對象模型,並研究了對象模型的基本結構。 您學習了如何使用對象,集合和枚舉在任何對象模型中找到的基本類型。 您還學習了如何使用Office對象模型中的對象和集合公開的屬性,方法和事件。

本章介紹了將Office對象模型暴露給.NET代碼的Office主互操作程序集。 您學習了如何在Visual Studio項目中使用和引用Office PIA。 本章還介紹了在對象瀏覽器中查看PIA時可以忽略的內容。

下一章將開始研究Office編程中使用的基本開發模式,並提供各種示例。

VSTO:使用C#開發Excel、Word【6】