VS.NET 2003整合環境外掛開發指南(一)

hljhrbsjf發表於2007-04-01

VS.NET 2003整合環境外掛開發指南

轉載請註明出處:http://www.cnblogs.com/dragon

一、 簡介――Visual Studio.NET外掛能做什麼?

Visual Studio.NET外掛能做很多事情,例如:

1、 編寫如CodeRush一樣的開發環境程式碼輔助工具

2、 編寫如CodeSmith這樣的程式碼模板工具

3、 編寫程式碼生成器,根據自定義的一些條件自動生成程式碼。如現在比較流行的一些程式碼生成工具,如果和開發環境整合,使用起來應該會更加方便。

4、 編寫如DataSetPryer這樣的除錯工具,可以在除錯時檢視DataSet的內容。

5、 甚至還可以在VS.NET裡整合Google搜尋引擎,或將MSN整合到VS.NET

這裡不再一一列舉,總而言之,凡是可以和Visual Studio.NET開發環境相關的,都能以外掛的形式進行。

開發VS.NET外掛,目前有兩種形式:一是利用VS嚮導生成的VS外接程式;二是利用微軟的VSIP開發包(Visual Studio Industry Partner:微軟合作伙伴計劃)。本文討論的是第一種方法。

二、 程式框架概述

Visual Studio.NET中選擇新建專案à其他專案à擴充套件性專案àVisual Studio.NET外接程式,按照嚮導生成程式碼,最後會生成兩個工程檔案,一個是外接程式專案,一個是外接程式安裝專案。可以在外接程式專案裡看到生成的專案檔案中有個connect.cs檔案,該檔案有以下幾個部分:

1、 類的繼承介面及其常量定義

[GuidAttribute("952A6CFF-8516-4DA0-B0BA-519CB9614525"), ProgId("STDTools.Connect")]

public class Connect : Object, Extensibility.IDTExtensibility2, IDTCommandTarget

{}

Connect類主要從兩個介面繼承,一個是Extensibility.IDTExtensibility2介面,該介面主要定義了下面幾個方法:

OnAddInsUpdate 方法:在環境中載入或解除安裝外接程式時發生。

OnBeginShutdown 方法:正在關閉環境時發生。

OnConnection 方法:將外接程式載入到環境中時發生。

OnDisconnection 方法:當從環境中解除安裝外接程式時發生。

OnStartupComplete 方法:環境啟動完畢時發生。

IDTCommandTarget介面則定義了以下兩個方法

Exec 方法:在VS開發環境中選擇了某個外接選單命令時被VS環境所呼叫。

QueryStatus方法:當VS環境要顯示外接選單時呼叫該方法查詢選單的狀態。

該方法返回指定的已命名命令的當前狀態,無論此命令是啟用、禁用還是隱藏

2、 OnConnection()函式:

本事件處理函式是在外掛被載入時發生,一般用於做一些初始化工作,如建立選單等。該函式的傳入引數如下:

object application:定義了IDE自動化物件

Extensibility.ext_ConnectMode connectMode:連線模式,指明瞭外掛當前的連線模式

ext_cm_AfterStartup 外接程式是在應用程式啟動後載入的,或是透過將相應 AddIn 物件的 Connect 屬性設定為 True 載入的。

ext_cm_Startup 外接程式是在啟動時載入的。

ext_cm_UISetup 外接程式自安裝後首次被啟動。

object addInInst:表示外接程式例項的 AddIn 物件。

ref System.Array custom: 一個 Variant 陣列,可以用來提供附加資料,一般不太常用。

3、 OnDisconnection()函式:系統解除安裝外掛時被呼叫

本事件處理函式是在外掛被解除安裝時發生,其傳入引數如下

Extensibility.ext_DisconnectMode disconnectMode:

ext_dm_HostShutdown:外接程式是在開發環境關閉時解除安裝的。

ext_dm_UserClosed:外接程式是在使用者清除“外接程式管理器”對話方塊中該外接程式的核取方塊時解除安裝的

ext_dm_UISetupComplete:外接程式是在環境安裝完成後和在 OnConnection 方法返回後解除安裝的。

ref System.Array custom:

4、 QueryStatus()函式:系統查詢選單狀態

該方法有四個傳入引數

CmdName 要檢查的命令的名稱。

NeededText

一個 常數,指定是否返回檢查資訊,如果返回,還指定返回資訊的型別。

vsCommandStatusTextWantedNone不返回資訊。

vsCommandStatusTextWantedName返回命令名。

vsCommandStatusTextWantedStatus返回命令狀態。

StatusOption

一個指定命令的當前狀態的 常數。

vsCommandStatusUnsupported 命令在此上下文中不受支援。

vsCommandStatusSupported 命令在此上下文中受支援。

vsCommandStatusEnabled 命令當前處於啟用狀態。

vsCommandStatusLatched 命令當前處於鎖存狀態。

vsCommandStatusNinched 留作將來使用。

vsCommandStatusInvisible 命令當前處於隱藏狀態。

CommandText

指定 vsCommandStatusTextWantedStatus 時返回的文字。

5、 Exec()函式:

VS開發環境中選擇了某個外接選單命令時被VS環境所呼叫,在這裡可以編寫自己的響應程式碼,例如執行自己的程式或彈出某個視窗。

三、 處理選單

OnConnect方法中可以進行一系列初始化工作,其中之一就是生成選單

1、 新增選單條選單和工具條選單

applicationObject = (_DTE)application;

addInInstance = (AddIn)addInInst;

if(connectMode == Extensibility.ext_ConnectMode.ext_cm_UISetup

|| connectMode == Extensibility.ext_ConnectMode.ext_cm_Startup)

{// 如果是安裝狀態或是外掛剛被啟動的狀態,則建立選單

object []contextGUIDS = new object[] { };

//獲取IDE環境的Command集合和CommandBar集合

Commands commands = applicationObject.Commands;

_CommandBars commandBars = applicationObject.CommandBars;

try

{

//選單條物件和工具條物件都是CommandBar型別

CommandBar menuObj,toolbarObj;

//生成新的子選單物件,將會被插入到選單條和工具條物件上

Command commandObj = commands.AddNamedCommand(addInInstance,

"PublishUserManage",

"新增使用者管理程式碼",

"新增使用者管理的程式碼",

true,

127,

ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported+(int)vsCommandStatus.vsCommandStatusEnabled

);

//如何確定在按鈕上顯示的點陣圖的ID,可以利用附錄中的工具

#region 相關幫助資訊

/*

返回一個 Command 物件

[C#]

public Command AddNamedCommand(

AddIn pAddIn, //用於新增新命令的 AddIn 物件

string Name, //新命令的名稱縮寫。AddNamedCommand 會自動給此縮寫加上前面類字首的

//ProgId("STDTools.Connect")中的"STDTools.Connect"以建立唯一的名稱

string ButtonText,//在命令繫結到以名稱而不是以圖示顯示的按鈕時使用的名稱

string Tooltip, //當使用者將滑鼠指標懸停在任何繫結到新命令的控制元件上時所顯示的文字

bool MSOButton, //指示指定命令的按鈕圖片是否是 Office 圖片。True = 按鈕圖片從

//Office資原始檔中獲取。False則表示按鈕的圖片資源來源於其他的檔案

int Bitmap, //在按鈕上顯示的點陣圖的 ID

object[] ppsaContextUIGUIDs,

//GUIDSafeArray,它確定啟用此命令的環境上下文(即除錯模式、設計模式等

int DisableFlags

//確定當您提供了 ContextUIGUIDs 而當前它們都不活動時,此命令的禁用狀態是不可見還是灰色的

);

DisabeFlags命令的當前狀態。

vsCommandStatusUnsupported 0 命令在此上下文中不受支援。

vsCommandStatusSupported 1 命令在此上下文中受支援。

vsCommandStatusEnabled 2 命令當前處於啟用狀態。

vsCommandStatusLatched 4 命令當前處於鎖存狀態。

vsCommandStatusNinched 8 留作將來使用。

vsCommandStatusInvisible 16 命令當前處於隱藏狀態。

這裡有幾點要說明:

1、選單圖片:

bool MSOButton引數為true,意味著該選單命令的圖片是來源於Office資源庫,則後面的int Bitmap(點陣圖ID號)則指明瞭是哪個圖片。如何知道哪個ID號對應哪個圖片?可以從微軟的頁面上下載一個用VBA寫的工具,該工具列舉出了所有的圖片資源(附錄工具中已經包含FaceID.xls)。

如果不想用Microsoft Office自帶的圖片資源,則需要先在自己的解決方案中新增一個MFC DLL的工程,然後在其中加入圖片資源;然後將MSOButton設為False,將Bitmap點陣圖ID設為該資原始檔中圖片資源的ID號,然後還要在安裝程式裡新增一個資料夾,同時新增登錄檔項。具體過程就不再多說了,可以看參考資料

2、選單項的名稱

函式的第二項引數string Name(本例中是PublishUserManage),系統在生成選單物件時會自動在Name前面新增本外掛的ProgID代表的字串作為選單物件的全名。後面在根據名稱檢索該選單物件時,需要用全名,本例中應該是STDTools.Connect.PublishUserManage;

*/

#endregion

//新增主選單

CommandBarButton buttonObj;

//建立主選單項和工具條

menuObj = (CommandBar) applicationObject.Commands.AddCommandBar("程式碼生成(&C)" ,

vsCommandBarType.vsCommandBarTypeMenu,

applicationObject.CommandBars["MenuBar"],10);

#region 相關幫助資訊

/*

public object AddCommandBar(

string Name,//新命令欄的名稱

vsCommandBarType Type,//用於確定命令欄型別的 vsCommandBarType 常數

CommandBar CommandBarParent,//要新增新命令欄的 Office CommandBar 物件

int Position// 命令欄中放置新命令欄的索引位置,從 1 開始

);

vsCommandBarType的取值為:

vsCommandBarTypePopup 10 彈出命令欄

vsCommandBarTypeToolbar 23 工具欄命令欄

vsCommandBarTypeMenu 24 選單命令欄

*/

#endregion 相關幫助資訊

toolbarObj = (CommandBar) applicationObject.Commands.AddCommandBar(

"CodeTools(&C)",

vsCommandBarType.vsCommandBarTypeToolbar,

null,

-1);

toolbarObj.Position = Microsoft.Office.Core.MsoBarPosition.msoBarTop;

//增加子選單

//將子選單加入主選單和工具條

buttonObj = (CommandBarButton) commandObj.AddControl(menuObj, menuObj.Controls.Count + 1);

buttonObj = (CommandBarButton) commandObj.AddControl(toolbarObj, toolbarObj.Controls.Count + 1);

buttonObj.Style = MsoButtonStyle.msoButtonIcon;

//將子選單加入Project的右鍵選單

CommandBar projBar = this.applicationObject.CommandBars["Project"];

commandObj.AddControl(projBar,1);

}

catch(System.Exception ex)

{

string error = ex.Message;

// MessageBox.Show(error);

}

2、 新增右鍵彈出快捷選單

除了上面在VS開發環境中新增常規選單外,還允許使用者為開發環境新增一些右鍵彈出選單項。下面程式碼是為程式碼編輯視窗新增右鍵彈出選單。

//檢索程式碼編輯視窗右鍵彈出選單的工具條

CommandBar projBar = this.applicationObject.CommandBars["Code Window"];

//將自己的選單項加入工具條

commandObj.AddControl(projBar,1);

如果想在滑鼠右鍵點選“解決方案資源管理器”中的某專案結點時彈出的選單條中新增自己的選單項,則只需把上面的"Code Window"改成"Project"即可。如何知道是"Code Window""Project"這個沒有什麼資料說明,但是也很簡單,只要編寫一個外掛程式,列舉出所有的選單條物件就行了。幸好筆者已經做了這件事情,把所有的選單條物件的名稱都列在附錄的CommandBar_Names.txt檔案裡了,你所要做的就是根據名稱去猜哪個是你所需要的選單條了。

3、 解除安裝選單

為什麼需要解除安裝選單?

因為如果在你的外掛中沒有處理解除安裝選單,則使用者透過“工具à外接程式管理器”暫時關閉了你的外掛,或者是透過新增/刪除程式解除安裝了你的外掛時,選單項依然存在,但是卻已經不能執行命令,這是不合理的。

public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode,

ref System.Array custom)

{

/*

CmdName 要檢查的命令的名稱。

NeededText

一個 vsCommandStatusTextWanted 常數,指定是否返回檢查資訊,

如果返回,還指定返回資訊的型別。

vsCommandStatusTextWantedNone不返回資訊。

vsCommandStatusTextWantedName返回命令名。

vsCommandStatusTextWantedStatus返回命令狀態。

StatusOption

一個指定命令的當前狀態的 vsCommandStatus 常數。

vsCommandStatusUnsupported 命令在此上下文中不受支援。

vsCommandStatusSupported 命令在此上下文中受支援。

vsCommandStatusEnabled 命令當前處於啟用狀態。

vsCommandStatusLatched 命令當前處於鎖存狀態。

vsCommandStatusNinched 留作將來使用。

vsCommandStatusInvisible 命令當前處於隱藏狀態。

CommandText

指定 vsCommandStatusTextWantedStatus 時返回的文字。

*/

try

{

if(disconnectMode == Extensibility.ext_DisconnectMode.ext_dm_HostShutdown

|| disconnectMode == Extensibility.ext_DisconnectMode.ext_dm_UserClosed )

{

Command commandObj = this.applicationObject.Commands.Item(

"STDTools.Connect.PublishUserManage",-1);

if(commandObj != null)

commandObj.Delete();

CommandBar menuObj = (CommandBar)

this.applicationObject.CommandBars["程式碼生成(&C)"];

CommandBar toolbarObj = (CommandBar)

this.applicationObject.CommandBars["CodeTools(&C)"];

if (menuObj != null)

{

this.applicationObject.Commands.RemoveCommandBar(menuObj);

}

if (toolbarObj != null)

{

this.applicationObject.Commands.RemoveCommandBar(toolbarObj);

}

}

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

}

上面的程式碼比較簡單,先判斷是不是VS環境正在關閉或使用者透過外接程式暫停了外掛,然後查詢到子選單項並刪除,再查詢到主選單項和工具條項,從系統選單集合裡移除掉這些命令條物件。

4、 確定選單狀態

選單顯示時有一項比較重要的工作,就是根據應用環境的不同,選單物件的顯示狀態也在不斷變化。也即可用,禁用,不顯示。每當VS整合環境要顯示一個外掛的選單時,它會呼叫QueryStatus()方法查詢該選單應該顯示的狀態。如下程式碼所示:

public void QueryStatus(string commandName,

EnvDTE.vsCommandStatusTextWanted neededText,

ref EnvDTE.vsCommandStatus status, ref object commandText)

{

/*

CmdName:要檢查的命令的名稱。

NeededText:一個 vsCommandStatusTextWanted 常數,指定是否返回檢查資訊,

如果返回,還指定返回資訊的型別。

status:一個指定命令的當前狀態的 vsCommandStatus 常數。

vsCommandStatusUnsupported 0 命令在此上下文中不受支援。

vsCommandStatusSupported 1 命令在此上下文中受支援。

vsCommandStatusEnabled 2 命令當前處於啟用狀態。

vsCommandStatusLatched 4 命令當前處於鎖存狀態。

vsCommandStatusNinched 8 留作將來使用。

vsCommandStatusInvisible 16 命令當前處於隱藏狀態

CommandText:指定 vsCommandStatusTextWantedStatus 時返回的文字。

*/

if(nee

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

相關文章