系列的第一篇逐步解說,建立基本專案系統,第 1 部分,展示了如何建立基本的專案系統。 本攻略在基本專案系統基礎上,新增了 Visual Studio 範本、屬性頁面及其他功能。 你必須先完成第一個流程,才能開始進行這個流程。
這個教學說明如何建立一個專案副檔名為 .myproj 的專案類型。 要完成攻略,你不需要自己創建語言,因為攻略借用了現有的 Visual C# 專案系統。
這個攻略教你如何完成以下任務:
建立一個 Visual Studio 範本。
部署 Visual Studio 範本。
在 新專案 對話框中建立專案類型的子節點。
在 Visual Studio 範本中啟用參數替換功能。
建立一個專案物業頁面。
備註
這個攻略的步驟是基於 C# 專案。 不過,除了例如副檔名和程式碼等具體細節外,Visual Basic 專案可以使用相同的步驟。
建立 Visual Studio 範本
- 建立一個基本的專案系統,第一部分 說明如何建立基本專案範本並將其加入專案系統。 它也展示了如何透過屬性 ProvideProjectFactoryAttribute 在 Visual Studio 註冊此範本,該屬性會寫入系統登錄檔中 \Templates\Projects\SimpleProject\ 資料夾的完整路徑。
透過使用 Visual Studio 範本(.vstemplate 檔案)取代基本專案範本,你可以控制範本在 新專案 對話框中的呈現方式,以及範本參數的替換方式。 .vstemplate 檔案是一個 XML 檔案,描述使用專案系統範本建立專案時,原始碼檔案應如何被納入。 專案系統本身是透過收集 .vstemplate 檔案與原始檔案組成 .zip 檔案,然後將 .zip 檔案複製到 Visual Studio 已知的位置來部署。 這個過程會在後面的攻略中更詳細說明。
在 Visual Studio 中,開啟你依照 Create a Basic Project System 第一部分建立的 SimpleProject 解決方案。
在 SimpleProjectPackage.cs 檔案中,找到 ProvideProjectFactory 屬性。 將第二個參數(專案名稱)替換為 null,第四個參數(專案範本資料夾的路徑)替換為「.\\NullPath」,如下。
[ProvideProjectFactory(typeof(SimpleProjectFactory), null, "Simple Project Files (*.myproj);*.myproj", "myproj", "myproj", ".\\NullPath", LanguageVsTemplate = "SimpleProject")]將一個名為 SimpleProject.vstemplate 的 XML 檔案加入 \Templates\Projects\SimpleProject\ 資料夾。
請將 SimpleProject.vstemplate 的內容替換為以下程式碼。
<VSTemplate Version="2.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005"> <TemplateData> <Name>SimpleProject Application</Name> <Description> A project for creating a SimpleProject application </Description> <Icon>SimpleProject.ico</Icon> <ProjectType>SimpleProject</ProjectType> </TemplateData> <TemplateContent> <Project File="SimpleProject.myproj" ReplaceParameters="true"> <ProjectItem ReplaceParameters="true" OpenInEditor="true"> Program.cs </ProjectItem> <ProjectItem ReplaceParameters="true" OpenInEditor="false"> AssemblyInfo.cs </ProjectItem> </Project> </TemplateContent> </VSTemplate>在 屬性 視窗中,選取 \Templates\Projects\SimpleProject\ 資料夾中的全部五個檔案,並將 建置動作 設為 ZipProject。
<TemplateData> 區塊決定了 SimpleProject 專案類型在新專案對話框中的位置與外觀,如下所示:
<Name> 元素將專案範本命名為 SimpleProject Application。
<描述>元素包含當選取專案範本時,會出現在新專案對話框中的描述。
<Icon> 元素指定與 SimpleProject 專案類型同時出現的圖示。
<ProjectType> 元素會在新專案對話框中命名專案類型。 此名稱取代了 ProvideProjectFactory 屬性中的專案名稱參數。
備註
<ProjectType> 元素必須與 SimpleProjectPackage.cs 檔案中屬性的參數
LanguageVsTemplate相符ProvideProjectFactory。<TemplateContent> 章節描述了在建立新專案時產生的這些檔案:
SimpleProject.myproj
Program.cs
AssemblyInfo.cs
這三個檔案都設
ReplaceParameters為 true,這讓參數替換成為可能。 Program.cs 檔案設定OpenInEditor為 true,當建立專案時,該檔案會在程式碼編輯器中被打開。欲了解更多關於 Visual Studio 範本結構中元素的資訊,請參閱 Visual Studio 範本架構參考。
備註
如果一個專案有多個 Visual Studio 範本,每個範本都放在獨立的資料夾裡。 該資料夾中的每個檔案都必須將 建置動作 設定為 ZipProject。
新增一個最小的 .vsct 檔案
Visual Studio 必須以設定模式執行,才能辨識新的或修改過的 Visual Studio 範本。 設定模式需要 .vsct 檔案存在。 因此,你必須在專案中加入一個最小的 .vsct 檔案。
在 SimpleProject 專案中新增一個名為 SimpleProject.vsct 的 XML 檔案。
請將 SimpleProject.vsct 檔案的內容替換為以下程式碼。
<?xml version="1.0" encoding="utf-8" ?> <CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable"> </CommandTable>將此檔案的 建置動作 設為 VSCTCompile。 你只能在 .csproj 檔案裡做這件事,不能在 屬性 視窗裡。 此時請確保此檔案的 建置動作 設為 無 。
右鍵點選 SimpleProject 節點,然後選擇 Edit SimpleProject.csproj。
在 .csproj 檔案中,找到 SimpleProject.vsct 項目。
<None Include="SimpleProject.vsct" />將建置動作改成 VSCTCompile。
<VSCTCompile Include="SimpleProject.vsct" />專案檔案,然後關閉編輯器。
儲存 SimpleProject 節點,然後在 解決方案總管 中選擇 重新載入專案。
檢視 Visual Studio 範本的建置步驟
當 .vstemplate 檔案被更改或包含 .vstemplate 檔案的專案被重建時,VSPackage 專案建置系統通常會以設定模式執行 Visual Studio。 你可以跟著把 MSBuild 的冗長程度設為普通或更高。
在 工具>選項 欄中,展開 「所有設定>、專案與解決方案>、建置與執行 」區塊。
將 MSBuild 專案建構輸出冗長度 選項設為 Normal。
在 工具>選項 對話框中,展開「 專案與解決方案>:建置與執行 」區塊。
將 MSBuild 專案建構輸出冗長度 選項設為 Normal,然後選擇 確定。
- 重建 SimpleProject 專案。
建立 .zip 專案檔案的建置步驟應該類似以下範例。
ZipProjects:
1> Zipping ProjectTemplates
1> Zipping <path>\SimpleProject\SimpleProject\obj\Debug\SimpleProject.zip...
1> Copying file from "<path>\SimpleProject\SimpleProject\obj\Debug\SimpleProject.zip" to "<%LOCALAPPDATA%>\Microsoft\VisualStudio\14.0Exp\ProjectTemplates\\\\SimpleProject.zip".
1> Copying file from "<path>\SimpleProject\SimpleProject\obj\Debug\SimpleProject.zip" to "bin\Debug\\ProjectTemplates\\\\SimpleProject.zip".
1> SimpleProject -> <path>\SimpleProject\SimpleProject\bin\Debug\ProjectTemplates\SimpleProject.zip
1>ZipItems:
1> Zipping ItemTemplates
1> SimpleProject ->
部署 Visual Studio 範本
Visual Studio 範本不包含路徑資訊。 因此,範本 .zip 檔案必須部署到一個 Visual Studio 已知的位置。 ProjectTemplates 資料夾的位置通常 <%LOCALAPPDATA%>\Microsoft\VisualStudio\14.0Exp\ProjectTemplates。
要部署你的專案工廠,安裝程式必須擁有管理員權限。 它會在 Visual Studio 安裝節點下部署範本: ...\Microsoft Visual Studio 14.0\Common7\IDE\ProjectTemplates。
測試 Visual Studio 範本
測試你的專案工廠,看看它是否透過 Visual Studio 範本建立專案階層。
重設 Visual Studio SDK 的實驗實例。
在 Windows 7 上:在 開始 選單中,找到 Microsoft Visual Studio/Microsoft Visual Studio SDK/Tools 資料夾,然後選擇 重置 Microsoft Visual Studio Experimental 實例。
針對更新版本的 Windows:在開始畫面 輸入 「重設 Microsoft Visual Studio <版本> 實驗性實例」。
會出現命令提示字元視窗。 當你看到「按任意鍵繼續」時,選擇 ENTER。 視窗關閉後,開啟 Visual Studio。
重建 SimpleProject 專案並開始除錯。 實驗實例隨即出現。
在實驗實例中,建立一個 SimpleProject 專案。 在 新專案 對話框中,選擇 SimpleProject。
你應該會看到一個新的 SimpleProject 實例。
建立專案類型子節點
你可以在 新專案 對話框中,將子節點加入專案類型節點。 例如,對於 SimpleProject 專案類型,你可以設置子節點給主控台應用程式、視窗應用程式、網頁應用程式等等。
子節點是透過修改專案檔案並在 ZipProject< 元素中加入 >OutputSubPath< 子>節點來建立的。 當範本在建置或部署時被複製,每個子節點都會成為專案範本資料夾的子資料夾。
本節展示如何為 SimpleProject 專案類型建立 Console 子節點。
將 \Templates\Projects\SimpleProject\ 資料夾重新命名為 \Templates\Projects\ConsoleApp\。
在 屬性 視窗中,選取 \Templates\Projects\ConsoleApp\ 資料夾中的全部五個檔案,並確保 建置動作 設為 ZipProject。
在 SimpleProject.vstemplate 檔案中,請在 TemplateData< 區段的結尾>、結束標籤前加上以下一行。
<NumberOfParentCategoriesToRollUp>1</NumberOfParentCategoriesToRollUp>這會導致主控台應用程式範本同時出現在主控台子節點與 SimpleProject 父節點中,後者位於子節點上一層。
儲存 SimpleProject.vstemplate 檔案。
在 .csproj 檔案中,為每個 ZipProject 元素新增 <OutputSubPath> 。 像之前一樣卸載專案,然後編輯專案檔案。
找到 <ZipProject> 的元素。 每個 <ZipProject> 元素都新增一個 <OutputSubPath> 元素,並賦予 Console 值。 Zip專案
<ZipProject Include="Templates\Projects\ConsoleApp\AssemblyInfo.cs"> <OutputSubPath>Console</OutputSubPath> </ZipProject> <ZipProject Include="Templates\Projects\ConsoleApp\Program.cs"> <OutputSubPath>Console</OutputSubPath> </ZipProject> <ZipProject Include="Templates\Projects\ConsoleApp\SimpleProject.myproj"> <OutputSubPath>Console</OutputSubPath> </ZipProject> <ZipProject Include="Templates\Projects\ConsoleApp\SimpleProject.vstemplate"> <OutputSubPath>Console</OutputSubPath> </ZipProject> <ZipProject Include="Templates\Projects\ConsoleApp\SimpleProject.ico"> <OutputSubPath>Console</OutputSubPath> </ZipProject>將此 <PropertyGroup> 加入專案檔案:
<PropertyGroup> <VsTemplateLanguage>SimpleProject</VsTemplateLanguage> </PropertyGroup>儲存專案檔案並重新載入專案。
測試專案類型子節點
測試修改後的專案檔案,看看 主控台 子節點是否出現在 新專案 對話框中。
執行 「重置 Microsoft Visual Studio 實驗實例 」工具。
重建 SimpleProject 專案並開始除錯。 實驗實例應該會出現
在 新專案 對話框中,選擇 SimpleProject 節點。 主控台應用程式範本應該會出現在範本面板中。
展開 SimpleProject 節點。 控制台 子節點應該會出現。 SimpleProject 應用程式範本仍會出現在範本面板中。
選擇 取消 並停止除錯。
替換專案範本參數
-
建立一個基本的專案系統,第一部分 展示了如何覆寫該
ProjectNode.AddFileFromTemplate方法,進行一種基本的模板參數替換。 本節教你如何使用更複雜的 Visual Studio 範本參數。
當你在 新專案 對話框中使用 Visual Studio 範本建立專案時,範本參數會被字串取代以自訂專案。 模板參數是一種特殊的標記,開頭和結尾都以美元符號為標誌,例如$time$。 以下兩個參數對於基於範本的專案中特別有用,以實現自訂功能:
$GUID[1-10]$ 被新的 Guid 取代。 你可以指定最多 10 個獨特的 GUID,例如$guid 1$。
$safeprojectname$ 是新 專案 對話框中使用者提供的名稱,經過修改以移除所有不安全的字元與空格。
完整的範本參數清單,請參見 範本參數。
替換專案範本參數
在 SimpleProjectNode.cs 檔案中,移除該
AddFileFromTemplate方法。在 \Templates\Projects\ConsoleApp\SimpleProject.myproj 檔案中,找到 <RootNamespace> 屬性並將其值改為 $safeprojectname$。
<RootNamespace>$safeprojectname$</RootNamespace>在 \Templates\Projects\SimpleProject\Program.cs 檔案中,請用以下程式碼替換該檔案的內容:
using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; // Guid namespace $safeprojectname$ { [Guid("$guid1$")] public class $safeprojectname$ { static void Main(string[] args) { Console.WriteLine("Hello VSX!!!"); Console.ReadKey(); } } }重建 SimpleProject 專案並開始除錯。 實驗實例應該會出現。
建立一個新的 SimpleProject 主控台應用程式。 (在 專案類型 選區,選擇 SimpleProject。在 Visual Studio 安裝範本中,選擇主 控台應用程式。)
在新成立的專案中,開放 Program.cs。 它應該看起來像這樣(你檔案中的 GUID 值不同):
using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; // Guid namespace Console_Application1 { [Guid("00000000-0000-0000-00000000-00000000)"] public class Console_Application1 { static void Main(string[] args) { Console.WriteLine("Hello VSX!!!"); Console.ReadKey(); } } }
建立專案物業頁面
你可以為你的專案類型建立屬性頁面,讓使用者能查看並更改基於你範本的專案屬性。 本節會展示如何建立一個與設定無關的屬性頁面。 這個基本的屬性頁面使用屬性網格來顯示你在屬性頁面類別中暴露的公開屬性。
請從SettingsPage基底類別衍生您的屬性頁面類別。 類別提供的 SettingsPage 屬性網格知道大多數原始資料型態,並知道如何顯示它們。 此外,這個 SettingsPage 類別知道如何將屬性值持久化到專案檔案中。
你在本區建立的屬性頁面允許你修改和儲存這些專案屬性:
組件名稱
輸出類型
根命名空間
在 SimpleProjectPackage.cs 檔案中,將這個
ProvideObject屬性加入類別:SimpleProjectPackage[ProvideObject(typeof(GeneralPropertyPage))] public sealed class SimpleProjectPackage : ProjectPackage這會將屬性頁類別
GeneralPropertyPage註冊給 COM。在 SimpleProjectNode.cs 檔案中,將這兩個重載方法加入到
SimpleProjectNode類別中:protected override Guid[] GetConfigurationIndependentPropertyPages() { Guid[] result = new Guid[1]; result[0] = typeof(GeneralPropertyPage).GUID; return result; } protected override Guid[] GetPriorityProjectDesignerPages() { Guid[] result = new Guid[1]; result[0] = typeof(GeneralPropertyPage).GUID; return result; }這兩種方法都會回傳一組屬性頁的 GUID。 GeneralPropertyPage GUID 是陣列中唯一的元素,因此 Property Pages 對話框只顯示一個頁面。
在 SimpleProject 專案中新增一個名為 GeneralPropertyPage.cs 的類別檔案。
請使用以下程式碼替換此檔案的內容:
using System; using System.Runtime.InteropServices; using Microsoft.VisualStudio; using Microsoft.VisualStudio.Project; using System.ComponentModel; namespace SimpleProject { [ComVisible(true)] [Guid("6BC7046B-B110-40d8-9F23-34263D8D2936")] public class GeneralPropertyPage : SettingsPage { private string assemblyName; private OutputType outputType; private string defaultNamespace; public GeneralPropertyPage() { this.Name = "General"; } [Category("AssemblyName")] [DisplayName("AssemblyName")] [Description("The output file holding assembly metadata.")] public string AssemblyName { get { return this.assemblyName; } } [Category("Application")] [DisplayName("OutputType")] [Description("The type of application to build.")] public OutputType OutputType { get { return this.outputType; } set { this.outputType = value; this.IsDirty = true; } } [Category("Application")] [DisplayName("DefaultNamespace")] [Description("Specifies the default namespace for added items.")] public string DefaultNamespace { get { return this.defaultNamespace; } set { this.defaultNamespace = value; this.IsDirty = true; } } protected override void BindProperties() { this.assemblyName = this.ProjectMgr.GetProjectProperty("AssemblyName", true); this.defaultNamespace = this.ProjectMgr.GetProjectProperty("RootNamespace", false); string outputType = this.ProjectMgr.GetProjectProperty("OutputType", false); this.outputType = (OutputType)Enum.Parse(typeof(OutputType), outputType); } protected override int ApplyChanges() { this.ProjectMgr.SetProjectProperty("AssemblyName", this.assemblyName); this.ProjectMgr.SetProjectProperty("OutputType", this.outputType.ToString()); this.ProjectMgr.SetProjectProperty("RootNamespace", this.defaultNamespace); this.IsDirty = false; return VSConstants.S_OK; } } }該
GeneralPropertyPage類別暴露了三個公開屬性:AssemblyName、OutputType 和 RootNamespace。 因為 AssemblyName 沒有固定方法,所以它會以唯讀屬性顯示。 OutputType 是一個列舉型常數,因此會被顯示為下拉選單的形式。SettingsPage基底類別提供ProjectMgr持久化這些屬性的功能。 此BindProperties方法用ProjectMgr來取得持久的屬性值並設定相應的屬性。 這個ApplyChanges方法用ProjectMgr來取得屬性的數值,並將其持久化到專案檔案。 屬性設置方法將IsDirty設為 true,以表示屬性必須被持久化。 持久性發生在你儲存專案或解決方案時。重建 SimpleProject 解決方案並開始除錯。 實驗實例應該會出現。
在實驗實例中,建立一個新的 SimpleProject 應用程式。
Visual Studio 呼叫你的專案工廠,透過 Visual Studio 範本建立專案。 新的 Program.cs 檔案會在程式碼編輯器中開啟。
在 解決方案總管中右鍵點擊專案節點,然後選擇 屬性。 會顯示 「物業頁面 」對話框。
測試專案屬性頁面
現在你可以測試是否能修改和更改屬性值。
在 MyConsoleApplication 屬性頁面 對話框中,將 DefaultNamespace 改為 MyApplication。
選擇 OutputType 屬性,然後選擇 Class Library。
選取 [套用],然後選取 [確定] 。
重新開啟物業頁面對話框,確認你的變更是否被持續存在。
關閉實驗版的 Visual Studio 實例。
重新開啟實驗實例。
重新開啟物業頁面對話框,確認你的變更是否被持續存在。
關閉實驗版的 Visual Studio 實例。