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

後記:完成這篇文章的時候,已經離開始寫這篇文章有兩個星期的時間了。一開始是沒有時間寫,拖的久了也就不想寫了。所以後面的內容寫的不夠詳細。