VS 2008 Package 備忘
- 2019 年 10 月 5 日
- 筆記
今天研究了一下vs 2008 package的部署,即怎樣放置package中的dll、ProjectTemplate和ItemTemplate,趁着熱乎勁先記錄下來,免得以後忘記。
首先,創建一個簡單的package,供測試之用。
打開visual studio 2008,新建項目,選擇其他項目類型->擴展性->Visual Studio Integration Package,輸入項目名稱為DeployPackage,如下圖:

點擊確定後,彈出創建package的嚮導,選擇C#作為開發語言,選中Menu Command。如下兩圖:


完成嚮導後,vs幫我們創建了空的package項目,如下圖:

雙擊Guids.cs文件,添加一個guid,作為接下來要創建的ProjectFactory的guid,修改後的Guids.cs文件如下:
1: using System; 2: 3: namespace Company.DeployPackage 4: { 5: static class GuidList 6: { 7: public const string guidDeployPackagePkgString = "bad3390c-b2a2-4bfc-a3ad-87e8119df413"; 8: public const string guidDeployPackageCmdSetString = "b09083be-4856-4364-8bb1-243d133c7177"; 9: 10: 11: //該Guid為接下來要創建的ProjectFactory的guid 12: public const string guidDixProjectFactoryString = "9819EC75-61CC-468c-9823-E853AEE0FE8C"; 13: 14: public static readonly Guid guidDeployPackageCmdSet = new Guid(guidDeployPackageCmdSetString); 15: }; 16: }
新增一個ProjectFactory,名為DixProjectFactory,如下:
1: using System; 2: using System.Runtime.InteropServices; 3: using Microsoft.VisualStudio.Project; 4: using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider; 5: 6: namespace Company.DeployPackage 7: { 8: //注意這個guid 9: [Guid(GuidList.guidDixProjectFactoryString)] 10: public class DixProjectFactory : ProjectFactory 11: { 12: public DixProjectFactory(DeployPackagePackage package) 13: : base(package) 14: { 15: } 16: 17: protected override ProjectNode CreateProject() 18: { 19: DixProjectNode node = new DixProjectNode(); 20: node.SetSite((IOleServiceProvider)((IServiceProvider)Package).GetService(typeof(IOleServiceProvider))); 21: return node; 22: } 23: } 24: }
注意DixProjectFactory的Guid就是剛剛在Guids.cs文件中的那個Guid。
注意:需要下載MPFProjectBase才能使用ProjectFactory,以及下面的ProjectNode、ProjectPackage
新增一個ProjectNode類,名為DixProjectNode,如下:
1: using System; 2: using Microsoft.VisualStudio.Project; 3: 4: namespace Company.DeployPackage 5: { 6: public class DixProjectNode : ProjectNode 7: { 8: /// <summary> 9: /// 返回DixProjectFactory的Guid 10: /// </summary> 11: public override Guid ProjectGuid 12: { 13: get { return typeof(DixProjectFactory).GUID; } 14: } 15: 16: public override string ProjectType 17: { 18: get { return "Dix"; } 19: } 20: } 21: }
修改DeployPackagePackage類,使它繼承於ProjectPackage(原來是繼承與Package的),並添加一個ProvideProjectFactoryAttribute,如下:
1: ... 2: [ProvideProjectFactory(typeof(DixProjectFactory), "我的dix項目", "Dix Project Files (*.dixproj);*.dixproj", "dixproj", "dixproj", "", LanguageVsTemplate = "DiX")] 3: public sealed class DeployPackagePackage : ProjectPackage 4: { 5: ... 6: }
修改DeployPackagePackage類的Initialize方法,添加RegisterProjectFactory(new DixProjectFactory(this))語句,修改後的Initialize方法如下:
1: protected override void Initialize() 2: { 3: Trace.WriteLine (string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString())); 4: base.Initialize(); 5: 6: // Add our command handlers for menu (commands must exist in the .vsct file) 7: OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; 8: if ( null != mcs ) 9: { 10: // Create the command for the menu item. 11: CommandID menuCommandID = new CommandID(GuidList.guidDeployPackageCmdSet, (int)PkgCmdIDList.cmdidMyCommand); 12: MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID ); 13: mcs.AddCommand( menuItem ); 14: } 15: 16: //註冊ProjectFactory 17: RegisterProjectFactory(new DixProjectFactory(this)); 18: }
下面為該package添加ProjectTemplate和ItemTemplate。
添加Templates、Projects、Items等文件夾和文件,添加後如下圖:

注意這裏面的cs文件需要改一下Build Action,否則編譯不過。也可以把這堆文件的Build Action設置成ZipProject和ZipItem,但為了更加清楚模板的部署方式,我只是把他們的Build Action設置成了None。
Projects文件夾中放置Project模板,Items文件夾中放置ProjectItem模板。
Project模板以WinForm為例,要注意WinForm.vstemplate文件,該文件的定義如下:
<VSTemplate Version="2.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005"> <TemplateData> <Name>DiX WinForm Application</Name> <Description>Create Dix WinForm Application</Description> <Icon>WinForm.ico</Icon> <!--ProjectType要和Package里的LanguageVsTemplate相同--> <ProjectType>DiX</ProjectType> <SortOrder>20</SortOrder> <NumberOfParentCategoriesToRollUp>1</NumberOfParentCategoriesToRollUp> <CreateNewFolder>true</CreateNewFolder> <DefaultName>WinFormApplication</DefaultName> <ProvideDefaultName>true</ProvideDefaultName> <PromptForSaveOnCreation>false</PromptForSaveOnCreation> </TemplateData> <TemplateContent> <Project File="WinForm.dixproj" TargetFileName="$safeprojectname$.dixproj" ReplaceParameters="true"> <ProjectItem ReplaceParameters="true" OpenInEditor="true" TargetFileName="Form1.dix">Form1.dix</ProjectItem> </Project> </TemplateContent> </VSTemplate>
ProjectItem模板以Class為例,要注意Class.vstemplate文件,該文件的定義如下:
<?xml version="1.0" encoding="utf-8"?> <VSTemplate Version="3.0.0" Type="Item" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005"> <TemplateData> <Name Package="{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}" ID="2245" /> <Description Package="{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}" ID="2262" /> <Icon Package="{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}" ID="4515" /> <TemplateID>Dix.Class</TemplateID> <ProjectType>Dix</ProjectType> <RequiredFrameworkVersion>2.0</RequiredFrameworkVersion> <NumberOfParentCategoriesToRollUp>1</NumberOfParentCategoriesToRollUp> <DefaultName>Class.cs</DefaultName> </TemplateData> <TemplateContent> <ProjectItem ReplaceParameters="true">Class.cs</ProjectItem> </TemplateContent> </VSTemplate>
在這兩個vstemplate文件里,ProjectType要和DeployPackagePackage類聲明中的ProvideProjectFactoryAttribute標記的LanguageVsTemplate相同,即都要是「Dix」。其他的文件是隨便寫的,裏面的內容對於本次測試並不重要。
好了,用於測試的Package已經做完了,編譯成功後,下面開始測試如何在vs 2008里應用它。
1.在visual studio Experimental hive中測試
在visual studio Experimental hive中測試比較簡單,不需要再手動註冊package了,因為我們的Package項目在編譯成功後已經被自動註冊到visual studio Experimental hive中了。編譯時的輸出片段如下:
1: f:Microsoft Visual Studio 2008 SDKVisualStudioIntegrationToolsbinRegPkg.exe /root:SoftwareMicrosoftVisualStudio9.0Exp "/pkgdeffile:objDebugDeployPackage.pkgdef" "D:DeployPackageDeployPackagebinDebugDeployPackage.dll" 2: f:Microsoft Visual Studio 2008 SDKVisualStudioIntegrationToolsbinRegPkg.exe /root:SoftwareMicrosoftVisualStudio9.0Exp /ranu /codebase "D:DeployPackageDeployPackagebinDebugDeployPackage.dll" 3: C:Program FilesMicrosoft Visual Studio 9.0Common7IDEdevenv.com /rt "SoftwareMicrosoftVisualStudio9.0Exp" /RANU /setup /nosetupvstemplates
前兩句執行完之後,在註冊表的HKEY_CURRENT_USERSoftwareMicrosoftVisualStudio9.0ExpConfigurationInstalledProducts下可以看到該package的名稱,在HKEY_CURRENT_USERSoftwareMicrosoftVisualStudio9.0ExpConfigurationPackages可以看到以該package的GUID為名的子項,在Projects,Menus等目錄下也可以找到該package的信息。
編譯成功後,點擊開始菜單,依次選擇所有程序,Microsoft Visual Studio 2008 SDK,Tools,Start Microsoft Visual Studio 2008 SP1 under Experimental hive打開visual studio Experimental hive,可以看到在工具菜單下已經有了我們的package中的Menu Command,但是新建一個項目的時候,並沒有出現我們的項目模板。這是因為我們並沒有把模板部署到vs。
注意上面的編譯時輸出的第3句C:Program FilesMicrosoft Visual Studio 9.0Common7IDEdevenv.com /rt "SoftwareMicrosoftVisualStudio9.0Exp" /RANU /setup /nosetupvstemplates,這句命令最後有個/nosetupvstemplates的開關,意思是不需要安裝vstemplate。編譯package自動加上這個開關的原因是vs並不知道我們的package中存在template,如果我們把上面那堆模板文件設置成ZipProject或者ZipItem的話,vs在編譯這個package的時候,就不會自動加這個開關了,這樣編譯後,模板就會自動拷貝到vs識別的目錄里。
由於我並沒有設置Build Action為ZipProject或者ZipItem,所以現在要手動的去壓縮模板:
將Project模板分別壓縮成WinForm.zip和ConsoleApp.zip,在C:Documents and SettingsUser NameApplication DataMicrosoftVisualStudio9.0ExpProjectTemplates下建立Dix目錄,並在Dix目錄下建立Windows和控制台兩個子目錄,把WinForm.zip和ConsoleApp.zip分別放到這兩個目錄下。
將ProjectItem模板分別壓縮成WinForm.zip和Class.zip,在C:Documents and SettingskongxiangxinApplication DataMicrosoftVisualStudio9.0ExpItemTemplates下建立Dix目錄,並在Dix目錄下建立Windows Form和代碼兩個子目錄,把WinForm.zip和Class.zip分別放到這兩個目錄下。
注意,在壓縮成zip文件的時候,只壓縮文件,不要把文件夾整個壓縮。
運行"C:Program FilesMicrosoft Visual Studio 9.0Common7IDEdevenv.com" /rt "SoftwareMicrosoftVisualStudio9.0Exp" /RANU /installvstemplates,等這條命令運行成功後,啟動visual studio Experimental hive,新建項目,可以看到項目模板已經出現在新建項目對話框里了。

新建一個Dix WinForm Application的項目,然後添加新項,可以看到項模板出現在添加新項對話框里:

2.在visual studio中測試
在visual studio里測試需要自己運行命令去註冊package,可以參考package編譯時執行的命令,把root參數和ranu參數去掉就可以了:
1: f:Microsoft Visual Studio 2008 SDKVisualStudioIntegrationToolsbinRegPkg.exe /codebase "D:DeployPackageDeployPackagebinDebugDeployPackage.dll" 2: 3: C:Program FilesMicrosoft Visual Studio 9.0Common7IDEdevenv.com /setup
後記:完成這篇文章的時候,已經離開始寫這篇文章有兩個星期的時間了。一開始是沒有時間寫,拖的久了也就不想寫了。所以後面的內容寫的不夠詳細。