使用Visual C# .net生成Office COM 外接程式

ljm0211發表於2012-07-02
本文的釋出號曾為 CHS302901本頁 概要Microsoft Office XP 和 Microsoft Office 2003 都支援一種新的統一的設計結構,這種結構用於生成應用程式外接程式以增強和控制 Office 應用程式。這些外接程式叫做 COM 外接程式。本文逐步討論了 Office COM 外接程式,並介紹瞭如何使用 Microsoft Visual C# .NET 生成 Office COM 外接程式。

IDTExensibility2 介面COM 外接程式是一種程式內 COM 伺服器或 ActiveX 動態連結庫 (DLL),它實現如 Microsoft 外接程式設計器型別庫 (Msaddndr.dll) 中所描述的 IDTExensibility2 介面。所有 COM 外接程式都從此介面繼承而來,而且都必須實現其五個方法中的每一個方法。

OnConnection每當連線 COM 外接程式時,都會激發 OnConnection 事件。外接程式可以在啟動時連線、由終端使用者連線或者透過自動化來連線。如果 OnConnection 成功地返回,就表明已載入了外接程式。如果返回錯誤訊息,那麼宿主應用程式就立即釋放其對該外接程式的引用,而且該物件將被銷燬。

OnConnection 使用下列四個引數: • Application — 一個對宿主應用程式物件的引用。 • ConnectMode — 一個指定外接程式連線方式的常量。外接程式可以採取下列幾種方式連線: • ext_cm_AfterStartup — 外接程式由終端使用者從 COM 外接程式 對話方塊啟動。 • ext_cm_CommandLine — 外接程式從命令列連線。注意,此方式不適用於生成 Office 應用程式的 COM 外接程式。 • ext_cm_External — 外接程式由外部應用程式透過自動化連線。請注意,此方式不適用於生成 Office 應用程式的 COM 外接程式。 • ext_cm_Startup — 外接程式由宿主在應用程式啟動時啟動。此行為由登錄檔中的設定來控制。 • AddInInst — 一個對 COMAddIn 物件的引用,它引用宿主應用程式的 COMAddIns 集合中的此外接程式。 • Custom — 一個包含 Variant 型別值的陣列,它可以儲存使用者定義的資料。 OnDisconnection當 COM 外接程式斷開連線並且在它從記憶體中解除安裝之前,將激發 OnDisconnection 事件。外接程式應在此事件中執行所有資源清理操作,並還原對宿主應用程式所做的任何更改。

OnDisconnection 使用下列兩個引數: • RemoveMode — 一個指定外接程式斷開連線的方式的常量。外接程式可以採用下列方式斷開連線: • ext_dm_HostShutdown —外接程式在宿主應用程式關閉時斷開連線。 • ext_dm_UserClosed — 外接程式由終端使用者或自動化控制器斷開連線。 • Custom — 一個包含 Variant 型別值的陣列,它可以儲存使用者定義的資料。 OnAddInsUpdate當註冊的 COM 外接程式集發生變化時,將激發 OnAddInsUpdate 事件。換言之,每當安裝 COM 外接程式或者從宿主應用程式中刪除 COM 外接程式時,都會激發此事件。

OnStartupComplete 和 OnBeginShutdown當宿主應用程式在忙於向記憶體中載入自身或者從記憶體中解除安裝自身時應避免使用者互動,而 OnStartupCompleteOnBeginShutdown 方法都是在宿主應用程式已離開或正要進入這一狀態時被呼叫的。只有在啟動期間已連線了外接程式的情況下才呼叫 OnStartupComplete,只有宿主在關閉過程中要斷開與外接程式的連線的情況下才呼叫 OnBeginShutdown

由於在激發這些事件時宿主應用程式的使用者介面是完全活動的,因此它們可能是執行某些操作的唯一途徑,以其他途徑將無法從 OnConnectionOnDisconnection 中執行這些操作。

COM 外接程式註冊除了正常的 COM 註冊外,COM 外接程式還需要向其執行所在的每一個 Office 應用程式註冊自身。為了向特定應用程式註冊其自身,外接程式應使用其 ProgID 作為項名稱在以下位置下建立一個子項:HKEY_CURRENT_USER\Software\Microsoft\Office\OfficeApp\Addins\ProgID外接程式可以在此項的位置為好記的顯示名稱和完整的說明提供值。此外,外接程式應使用一個名為 LoadBehavior. 的 DWORD 值指定所希望的載入行為。此值確定宿主應用程式如何載入外接程式,而且它由下列值的組合組成: • 0 = Disconnect — 未載入。 • 1 = Connected — 已載入。 • 2 = Bootload — 在應用程式啟動時載入。 • 8 = DemandLoad — 只在由使用者請求時載入。 • 16 = ConnectFirstTime — 只載入一次(在下次啟動時)。 通常指定 0x03 (Connected | Bootload) 這一典型的值。

實現了 IDTExtensibility2 的外接程式還應指定一個名為 CommandLineSafe 的 DWORD 值,以指出外接程式對於不支援使用者介面的操作是否安全。值為 0x00 表示 False,值為 0x01 則表示 True。

如何使用 Visual C# .NET 生成 COM 外接程式如上文所 述,Office COM 外接程式是由 Office 應用程式透過 COM 執行時層啟用的程式內 COM 伺服器。因此,為了在 .NET 中開發 COM 外接程式,外接程式元件需要在 .NET 中實現,然後透過 COM interop 層向 COM 客戶端(即 Office 應用程式)公開。

要在 Visual C# .NET 中建立 COM 外接程式,請按照下列步驟操作: 1. 在 Visual C# .NET 中,建立一個類庫專案。 2. 新增一個對實現了 IDTExtensibility2 的型別庫的引用。此項的主 interop 程式集已經出現在 Extensibility 名稱下。 3. 新增一個對 Microsoft Office 物件庫的引用。此項的主 interop 程式集已經出現在 Office 名稱下。 4. 在實現了 IDTExtensibility2 的類庫中建立一個公共類。 5. 生成該類庫之後,將該庫向 COM interop 進行註冊。為此,需要為此類庫生成一個使用強名稱的程式集,然後將它註冊到 COM interop。可以使用 Regasm.exe 來向 COM interop 註冊 .NET 元件。 6. 建立登錄檔條目以使 Office 應用程式可以識別並載入外接程式。 您可以選擇完成所有這些步驟,或可以建立型別為共享的外接程式 的 .NET 專案。這將啟動“擴充套件性向導”,該向導可幫助您在 .NET 中建立 COM 外接程式。

“擴充套件性向導”將建立一個 Visual C# .NET 類庫專案,同時建立一個實現了 IDTExtensibility2 介面的 Connect 類。它還會生成實現 IDTExtensibility 的空成員的主幹程式碼。此專案具有對 Extensibility 和 Office 程式集的引用。該專案的生成設定中已選中了註冊 COM interop。將生成程式集金鑰 (.snk) 檔案,並在 Assemblyinfo.vb 檔案的 AssemblyKeyfile 屬性中進行引用。

除類庫專案外,該向導還將生成一個安裝專案,該專案可用於在其他計算機上部署 COM 外接程式。在需要時可以刪除此專案。

分步示例 1. 在 Microsoft Visual Studio .NET 的檔案選單上,單擊新建,然後單擊專案。 2. 在新建專案對話方塊中,展開專案型別下的其他專案,選擇擴充套件性專案,然後選擇共享的外接程式模板。 3. 鍵入 MyCOMAddin 作為該外接程式的名稱,然後單擊確定。 4. “擴充套件性向導”出現後,請按照下列步驟操作: a. 在第 1 頁,選擇使用 Visual C# 建立外接程式,然後單擊下一步。 b. 在第 2 頁,選擇下面的宿主應用程式,然後單擊下一步: • Microsoft Word • Microsoft PowerPoint • Microsoft Outlook • Microsoft Excel • Microsoft Access c. 在第 3 頁上,輸入該外接程式的名稱和描述,然後單擊下一步

注意:該外接程式的名稱和描述出現在 Office 應用程式的 COM 載入項對話方塊中。 d. 在第 4 頁,選擇所有可用的選項,然後單擊下一步。 e. 單擊完成。 5. 在專案選單上,單擊新增引用。單擊元件列表中的 System.Windows.Forms.DLL,單擊選擇,然後單擊確定。 6. 將下列程式碼新增到 Connect 類中的名稱空間列表中: using System.Reflection; 7. 將下列成員新增到 Connect 類中: private CommandBarButton MyButton; 8. 在 Connect 類中實現 IDTExtensibility2 的成員的程式碼,如下所示: public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom) {
applicationObject = application;
addInInstance = addInInst;

if(connectMode != Extensibility.ext_ConnectMode.ext_cm_Startup)
{
OnStartupComplete(ref custom);
}

}

public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom) {
if(disconnectMode != Extensibility.ext_DisconnectMode.ext_dm_HostShutdown)
{
OnBeginShutdown(ref custom);
}
applicationObject = null;
}


public void OnAddInsUpdate(ref System.Array custom)
{
}

public void OnStartupComplete(ref System.Array custom)
{
CommandBars oCommandBars;
CommandBar oStandardBar;

try
{
oCommandBars = (CommandBars)applicationObject.GetType().InvokeMember("CommandBars", BindingFlags.GetProperty , null, applicationObject ,null);
}
catch(Exception)
{
// Outlook has the CommandBars collection on the Explorer object.
object oActiveExplorer;
oActiveExplorer= applicationObject.GetType().InvokeMember("ActiveExplorer",BindingFlags.GetProperty,null,applicationObject,null);
oCommandBars= (CommandBars)oActiveExplorer.GetType().InvokeMember("CommandBars",BindingFlags.GetProperty,null,oActiveExplorer,null);
}

// Set up a custom button on the "Standard" commandbar.
try
{
oStandardBar = oCommandBars["Standard"];
}
catch(Exception)
{
// Access names its main toolbar Database.
oStandardBar = oCommandBars["Database"];
}

// In case the button was not deleted, use the exiting one.
try
{
MyButton = (CommandBarButton)oStandardBar.Controls["My Custom Button"];
}
catch(Exception)
{
object missing = System.Reflection.Missing.Value ;
MyButton = (CommandBarButton) oStandardBar.Controls.Add(1, omissing , omissing , omissing , omissing);
MyButton.Caption = "My Custom Button";
MyButton.Style. = MsoButtonStyle.msoButtonCaption;
}

// The following items are optional, but recommended.
//The Tag property lets you quickly find the control
//and helps MSO keep track of it when more than
//one application window is visible. The property is required
//by some Office applications and should be provided.
MyButton.Tag = "My Custom Button";

// The OnAction property is optional but recommended.
//It should be set to the ProgID of the add-in, so that if
//the add-in is not loaded when a user presses the button,
//MSO loads the add-in automatically and then raises
//the Click event for the add-in to handle.
MyButton.OnAction = "!";

MyButton.Visible = true;
MyButton.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.MyButton_Click);


object Name = applicationObject.GetType().InvokeMember("Name",BindingFlags.GetProperty,null,applicationObject,null);

// Display a simple message to show which application you started in.
System.Windows.Forms.MessageBox.Show("This Addin is loaded by " + oName.ToString() , "MyCOMAddin");
oStandardBar = null;
oCommandBars = null;
}

public void OnBeginShutdown(ref System.Array custom)
{
object missing = System.Reflection.Missing.Value ;
System.Windows.Forms.MessageBox.Show("MyCOMAddin Add-in is unloading.");
MyButton.Delete(omissing);
MyButton = null;
}

private void MyButton_Click(CommandBarButton cmdBarbutton,ref bool cancel) {
System.Windows.Forms.MessageBox.Show("MyButton was Clicked","MyCOMAddin"); } 9. 生成並測試該 COM 外接程式。為此,請按照下列步驟操作: a. 在生成選單上,單擊生成解決方案。請注意,生成 COM 外接程式的過程中實際上就向 COM interop 註冊了 .NET 類。 b. 啟動一個您選作外接程式的宿主應用程式的 Office 應用程式(例如,Microsoft Word 或 Microsoft Excel)。 c. 外接程式啟動之後,將激發其 OnStartupComplete 事件,您會收到一個訊息框。請關閉該訊息框。請注意,外接程式向標準工具欄中新增了一個新的標題為“My Custom Button”(我的自定義按鈕)的自定義按鈕。 d. 單擊 My Custom Button(我的自定義按鈕)。該按鈕的 Click 事件將由外接程式來處理,而且您會收到一個訊息框。請關閉該訊息框。 e. 退出該 Office 應用程式。 f. 退出該應用程式時,將激發 OnBeginShutDown 事件,您會收到一個訊息框。關閉該訊息框以結束演示。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/11411056/viewspace-734400/,如需轉載,請註明出處,否則將追究法律責任。

相關文章