vs多項(xiàng)目模板及add-in開發(fā)
2014-09-16 13:58 熬夜的蟲子 閱讀(4731) 評(píng)論(3) 收藏 舉報(bào)本文分2部分 第一為自定義多項(xiàng)目模板 第二為vs add-in開發(fā)
效果圖
1.自定義模板

2. 工具菜單

3.窗口

4.工程

5.文件

...
一. 多項(xiàng)目模板
單項(xiàng)目模板做起來很簡單 選中一個(gè)項(xiàng)目在文件一欄中選中導(dǎo)出模板


然后選擇項(xiàng)目模板

在最后一項(xiàng)向?qū)?huì)給出你的輸出路徑,一般都是系統(tǒng)的用戶文檔路徑+\Visual Studio 2010\My Exported Templates
在對(duì)應(yīng)目錄下會(huì)生成你對(duì)應(yīng)的項(xiàng)目模板壓縮包

我們生成2個(gè)項(xiàng)目的模板文件 然后做一個(gè)多項(xiàng)目模板
我們解壓2個(gè)模板文件并且放進(jìn)一個(gè)新建的名稱為MaoyaTemplates的文件夾 剪切到Visual Studio 2010\Templates\ProjectTemplates路徑下
新建模板文件MyTemplate.vstemplate

根據(jù)要定義的模板內(nèi)容 修改文件

然后將整個(gè)文件夾壓縮成zip文件即可 在TemplateData可以定義一些自己需要的信息 例如icon定義你的模板圖標(biāo) 把圖標(biāo)文件放在相對(duì)路徑即可
然后重新打開vs 即可看到剛才作成的模板

打開以后就是定義的2個(gè)demo工程 相當(dāng)簡單
這樣就不用每次來新項(xiàng)目都去copy代碼了
二 vs插件
概念性的東西可以參考 http://msdn.microsoft.com/zh-cn/library/bb384200.aspx
vs插件可以幫助或者優(yōu)化你在vs開發(fā)過程的大部分窗口 它可以針對(duì)文件 針對(duì)項(xiàng)目 針對(duì)窗口 甚至針對(duì)不同的后綴做不同的處理
下面圖文+代碼介紹開發(fā)步驟(vs2010)

選擇插件項(xiàng)目 進(jìn)入向?qū)Ц鶕?jù)自己的場景選擇即可


中間向?qū)н^程略過 最后一步

完成向?qū)Ш?默認(rèn)工程框架如下

最關(guān)鍵的就是connect.cs文件
Connect 繼承了2個(gè)類 IDTExtensibility2, IDTCommandTarget

IDTExtensibility2 包含在實(shí)現(xiàn)接口時(shí)用作事件的方法。 每當(dāng)發(fā)生影響某個(gè)外接程序的事件時(shí)(如加載或卸載該外接程序時(shí))以及對(duì)該外接程序進(jìn)行任何更改時(shí),Visual Studio 都會(huì)調(diào)用這些方法。
IDTCommandTarget 接口使開發(fā)者得以在環(huán)境中實(shí)現(xiàn)命名命令。 并且以定義命令狀態(tài)或執(zhí)行命令。
每個(gè)方法的描述

中文版可以參考msdn
http://msdn.microsoft.com/zh-cn/library/extensibility.idtextensibility2.aspx
http://msdn.microsoft.com/zh-cn/library/envdte.idtcommandtarget.aspx
其中我們作為入門開發(fā) 需要關(guān)注得的是
OnConnection 為IDTExtensibility2的 main 方法,這是因?yàn)槊看渭虞d外接程序時(shí)都會(huì)調(diào)用該方法。 該方法為外接程序在加載時(shí)的入口點(diǎn),因此可以將要在外接程序啟動(dòng)時(shí)運(yùn)行的任何代碼放置在此處(或調(diào)用任何其他函數(shù))。
void OnConnection( Object Application, ext_ConnectMode ConnectMode, Object AddInInst, ref Array custom )
參數(shù)
Application
類型:System.Object
對(duì)集成開發(fā)環(huán)境 (IDE) 的一個(gè)實(shí)例 (DTE) 的引用,該實(shí)例是 Visual Studio 自動(dòng)化模型的根對(duì)象。
ConnectMode
類型:Extensibility.ext_ConnectMode
一個(gè) ext_ConnectMode 枚舉值,指示向 Visual Studio 中加載外接程序的方式。
AddInInst
類型:System.Object
一個(gè)對(duì)外接程序自己的實(shí)例的 AddIn 引用。 此引用存儲(chǔ)起來以供以后使用(如用于確定外接程序的父集合)。
custom
類型:System.Array
一個(gè)空數(shù)組,可用來傳遞在外接程序中使用的特定于主機(jī)的數(shù)據(jù)。
下面我們開始建一個(gè)工具欄(Tools)下的菜單
首先判斷加載方式
if (connectMode == ext_ConnectMode.ext_cm_UISetup || connectMode == ext_ConnectMode.ext_cm_Startup ||
connectMode == ext_ConnectMode.ext_cm_AfterStartup)
這里的ConnectMode來自一個(gè)枚舉 參考msdn http://msdn.microsoft.com/zh-cn/library/extensibility.ext_connectmode.aspx

然后添加注冊(cè)插件命令和窗口 關(guān)鍵代碼:
var toolsBar = commandBars[Tools];
if (toolsBar != null)
{
toolsSubPopup = (CommandBarPopup)toolsBar.Controls.Add(MsoControlType.msoControlPopup, Type.Missing, Type.Missing, 1, true);
toolsSubPopup.Caption = MainMenuName;
CommandBar toolsSubBar = toolsSubPopup.CommandBar;
Command command = commands.AddNamedCommand2(
_addInInstance,
MenuName1,
MenuName1,
MenuName1,
true,
190,
ref contextGUIDS,
(int)vsCommandStatus.vsCommandStatusUnsupported + (int)vsCommandStatus.vsCommandStatusEnabled);
command.AddControl(toolsSubBar);
command = commands.AddNamedCommand2(
_addInInstance,
MenuName2,
MenuName2,
MenuName2,
true,
190,
ref contextGUIDS,
(int)vsCommandStatus.vsCommandStatusUnsupported + (int)vsCommandStatus.vsCommandStatusEnabled);
command.AddControl(toolsSubBar, 2);
}
commandBars[Tools]表示命令欄中的工具欄,這里Tools實(shí)際為定義的字符串“Tools”。
CommandBarPopup表示彈出命令條。
_addInInstance表示當(dāng)前插件實(shí)例。
3個(gè)Menuname分別表示命令名稱的縮寫形式,UI顯示的名稱以及當(dāng)用戶將鼠標(biāo)指針懸停在任何綁定到新命令的控件上時(shí)所顯示的文本。
true表示下面的190 為 Microsoft Office 位圖的 ID。
ContextUIGUIDs表示GUID 確定哪些環(huán)境上下文 (即調(diào)試模式,設(shè)計(jì)模式,等等) 顯示命令。
vsCommandStatusValue確定命令的禁用條件是不可見或禁用,當(dāng)您提供一個(gè) ContextUIGUIDs 參數(shù),并且都不是當(dāng)前活動(dòng)的。
AddNamedCommand2 創(chuàng)建命名命令,該命令由環(huán)境保存,并且在下次環(huán)境啟動(dòng)時(shí)(無論是否加載外接程序)可用。 外接程序以后可以通過響應(yīng) QueryStatus 方法來更改 ButtonText 名稱。 如果文本以 # 開頭,則該字符串的其余部分是一個(gè)整數(shù),該整數(shù)表示外接程序已注冊(cè)的附屬 DLL 中的資源 ID。有兩個(gè)默認(rèn)值順序狀態(tài):該默認(rèn)值啟用了狀態(tài)和默認(rèn)值可見性狀態(tài)。 這些默認(rèn)狀態(tài)很重要,如果找不到命令處理程序 (因?yàn)樵撛匚醇虞d或不實(shí)現(xiàn) IDTCommandTarget)。 如果您的組件加載并實(shí)現(xiàn) IDTCommandTarget,默認(rèn)值不適用。
Command.AddControl創(chuàng)建此命令的持久性命令欄控件。后面的數(shù)字表示菜單位置。
詳細(xì)參考http://msdn.microsoft.com/zh-cn/library/envdte80.commands2.addnamedcommand2.aspx
這樣基本上就完成了下圖所示的效果

但是我們需要對(duì)2個(gè)菜單進(jìn)行功能型的開發(fā)
QueryStatus方法返回指定的已命名命令的當(dāng)前狀態(tài)(啟用、禁用、隱藏等)。
在此方法添加片段
if (neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)
{
if (commandName == GetCommandName(MainMenuName))
{
status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
return;
}
}
vsCommandStatusSupported表示命令在此上下文中受支持,vsCommandStatusEnabled表示命令當(dāng)前處于啟用狀態(tài)。
Exec方法執(zhí)行指定的命名命令。
if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if (commandName == GetCommandName(MainMenuName))
{
MessageBox.Show("This is maoya test");
handled = true;
return;
}
if (commandName == GetCommandName(MenuName1))
{
MessageBox.Show("This is maoya Test1 test");
handled = true;
return;
}
if (commandName == GetCommandName(MenuName2))
{
MessageBox.Show("This is maoya Test2 test");
handled = true;
return;
}
}
這里實(shí)現(xiàn)的很簡單就是彈出個(gè)winform。你可以在這里實(shí)現(xiàn)很豐富的功能。

上面是工具欄的實(shí)現(xiàn),下面介紹個(gè)操作窗口的
Onconnection:
CommandBar mdiCommandBar = commandBars["Easy MDI Document Window"];
if (mdiCommandBar != null)
{
Command mdiCmd = commands.AddNamedCommand2(_addInInstance, MenuName3,
MenuName3,
MenuName3, false, 0,
ref contextGUIDS);
mdiCmd.AddControl(mdiCommandBar);
}
QueryStatus:
if (commandName == GetCommandName(MenuName3) || commandName == GetCommandName(MenuName4) || commandName == GetCommandName(MenuName5))
{
status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
return;
}
Exec 功能是新建一個(gè)文件
if (commandName == GetCommandName(MenuName3))
{
_applicationObject.ExecuteCommand("File.NewFile", string.Empty);
handled = true;
return;
}


下面我們?cè)谧鲆粋€(gè)針對(duì)項(xiàng)目工程的自定義按鈕
OnConnection:
CommandBar projectBar = commandBars["Project"];
if (projectBar != null)
{
projectSubPopup = (CommandBarPopup)projectBar.Controls.Add(MsoControlType.msoControlPopup, Type.Missing, Type.Missing, 1, true);
projectSubPopup.Caption = MainMenuName;
CommandBar projectSubBar = projectSubPopup.CommandBar;
Command projectCommand = commands.AddNamedCommand2(
_addInInstance,
MenuName4,
MenuName4,
MenuName4,
true,
190,
ref contextGUIDS,
(int)vsCommandStatus.vsCommandStatusUnsupported + (int)vsCommandStatus.vsCommandStatusEnabled);
if (projectSubBar != null)
{
projectCommand.AddControl(projectSubBar, 1);
}
}
QueryStatus:
if (commandName == GetCommandName(MenuName3) || commandName == GetCommandName(MenuName4) || commandName == GetCommandName(MenuName5))
{
status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
return;
}
Exec 這里可以抓到你選擇的是哪一個(gè)項(xiàng)目 包括名稱 路徑等等 根據(jù)具體的需求再來處理對(duì)應(yīng)的邏輯
if (commandName == GetCommandName(MenuName4))
{
MessageBox.Show(string.Format("This is maoya {0} test,/r/n該項(xiàng)目名稱為{1}", MenuName4, _applicationObject.SelectedItems.Item(1).Name));
handled = true;
return;
}


類似的還有操作文件,代碼就不貼了 直接上圖


值得一提你可以利用文件后綴等做一些特殊操作
在QueryStatus方法中添加
if (commandName == GetCommandName(MenuName6))
{
var uiHierarchy = (UIHierarchy)_applicationObject.Windows.Item(
Constants.vsWindowKindSolutionExplorer).Object;
if ((from UIHierarchyItem item in (Array)uiHierarchy.SelectedItems select item.Name).Any(itemName => itemName.IndexOf(".config") > -1))
{
status = vsCommandStatus.vsCommandStatusEnabled | vsCommandStatus.vsCommandStatusSupported;
}
}


希望對(duì)大家有幫助
![]() |
原創(chuàng)作品允許轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章原始出處以及作者信息。 作者:熬夜的蟲子 點(diǎn)擊查看:博文索引 |

浙公網(wǎng)安備 33010602011771號(hào)