前回、シンタックスハイライトまで作成しました。
今回は、カスタムプロジェクトを作成してみようと思います。
Managed Package Framework の追加
カスタムプロジェクトってなんぞやって話ですが、 C# のプロジェクトの場合は *.csproj
が、
Visual Basic の場合は *.vbproj
といったプロジェクト管理ファイルが生成されます。
このように、作成した言語サービスを対象とした .*proj
を追加する感じですね。
では、まずはじめに、 Python Tools for Visual Studio を適当な場所にクローンします。
GitHub - Microsoft/PTVS: Python Tools for Visual Studio
次に、 PTVS_ROOT\Common\Product\SharedProject
と進み、ファイルをすべてコピーします。
ちなみに、公式では Managed Package Framework for Projects を使用しています。
MPF for Projects - Visual Studio 2013 - Home
こっちは MS-PL であるため、 Apache である PTVS よりは使いにくいのかもしれません。
※なお、VS2013 となっていますが、 VS2015 でも使用できます。
追加したら、 References として、以下のものを追加します。
- Microsoft.Build
- Microsoft.Build.Tasks.v4.0
- Microsoft.Build.Utilities.v4.0
- Microsoft.VisualStudio.ComponentModelHost
- Microsoft.VisualStudio.Designer.Interfaces
- Microsoft.VisualStudio.Debugger.Interop
- Microsoft.VisualStudio.Editor
- Microsoft.VisualStudio.Language.IntelliSense
- Microsoft.VisualStudio.ProjectAggregator (※相互運用型の埋め込みを
False
にする) - VSLangProj
- VSLangProj2
- VSLangProj80
- WindowsBase
テンプレートの作成
次は、「新しく作成する」などに表示される、テンプレートを作ります。
適当なフォルダー(ここでは ProjectTemplates
)に作っていきます。
中身はこんな感じ。
ProjectTemplates |- ConsoleApplication |- ConsoleApplication.hsproj |- Program.hsp |- ConsoleApplication.vstemplate |- ConsoleApplication.ico
ConsoleApplication
というディレクトリを作成し、それぞれのファイルを作成します。
*.ico
と .hsp
はそれぞれ自由なアイコンとプロジェクトに含めるファイルです。
*.hsproj
はプロジェクト管理ファイルです。
C# だと *.csproj
に該当するファイルです。
*.csproj
と同じように、プロジェクト構成を記述していきます。
上記プロジェクトの場合だと、下のような構成になるはずです。
<?xml version="1.0" encoding="utf-8" ?> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <SchemaVersion>2.0</SchemaVersion> <ProjectGuid></ProjectGuid> <OutputType>Exe</OutputType> <AssemblyName>ConsoleApplication</AssemblyName> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <DebugSymbols>true</DebugSymbols> <OutputPath>bin\Debug\</OutputPath> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <DebugSymbols>false</DebugSymbols> <OutputPath>bin\Release\</OutputPath> </PropertyGroup> <ItemGroup> <Compile Include="Program.hsp"> <SubType>Code</SubType> </Compile> </ItemGroup> </Project>
最後は *.vstemplate
ですが、正直これはなくても読み込ませれるのですが、何らかの処理をさせる倍は
作成しておく必要があります。
*.vstemplate
の中身も XML なので、 *.hsproj
同様書いていきます。
<?xml version="1.0" encoding="utf-8"?> <VSTemplate Version="3.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005"> <TemplateData> <Name>Console Application</Name> <Description>A project for creating a new HSP3 Windows console application.</Description> <Icon>ConsoleApplication.png</Icon> <ProjectType>HSP</ProjectType> <SortOrder>20</SortOrder> <CreateNewFolder>true</CreateNewFolder> <DefaultName>ConsoleApplication</DefaultName> <ProvideDefaultName>true</ProvideDefaultName> <CreateInPlace>true</CreateInPlace> <PromptForSaveOnCreation>true</PromptForSaveOnCreation> </TemplateData> <TemplateContent> <Project TargetFileName="$safeprojectname$.hsproj" File="ConsoleApplication.hsproj" ReplaceParameters="true"> <ProjectItem OpenInEditor="true">Program.hsp</ProjectItem> </Project> </TemplateContent> </VSTemplate>
<TemplateData>
の子要素では、プロジェクト作成ダイアログに用いられている名前や説明、カテゴリーなどを、
<TemplateContent>
の子要素では、プロジェクトのアイテムと、その処理を記述しています。
それぞれの子要素についての詳しい解説は、 MSDN を参照してください。
テンプレートに含めるすべてのアイテムを作成し終えたら、アイテムをすべて選択し、
ビルドアクションを ZipProject
に設定します。
これでテンプレートの追加が完了しました。
なお、テンプレートの適用には、 VS ExpInstance のリセットを行う必要があります。
カスタムプロジェクトの登録~追加
前のセクションで *.hsproj
なテンプレートを追加しましたが、この状態では、
Visual Studio で扱うことができません。
Visual Studio で扱えるようにするためには、プロジェクトタイプを登録する必要があります。
プロジェクトタイプの登録には、別で Package
を提供します。
%ROOT_NAMESPACE%.Project
に HSPProjectPackage
クラスを追加し、以下のように記述します。
using System.ComponentModel.Composition; using System.Runtime.InteropServices; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudioTools.Project; namespace HSPToolsVS.Project { [PackageRegistration(UseManagedResourcesOnly = true)] [Guid(HSPToolsConstants.ProjectPackageGuid)] // Register project templates. [ProvideProjectFactory(typeof(HSPProjectFactory), null, "HSP Project File(*.hsproj);*.hsproj", "hsproj", "hsproj", @".\NullPath", LanguageVsTemplate = "HSP")] [Export] public sealed class HSPProjectPackage : CommonProjectPackage { #region Overrides of CommonProjectPackage public override ProjectFactory CreateProjectFactory() => new HSPProjectFactory(this); public override CommonEditorFactory CreateEditorFactory() => null; // Do not need. public override uint GetIconIdForAboutBox() => 0; // IconId is not defined. public override uint GetIconIdForSplashScreen() => 0; // IconID is not defined; public override string GetProductName() => "HSP"; public override string GetProductDescription() => "HSP"; public override string GetProductVersion() => GetType().Assembly.GetName().Version.ToString(); #endregion } }
ProvideProjectFactoryAttribute
にて、先ほど作成した *.hsproj
を扱えるように設定しています。
また、第 2 引数には言語名を指定できるのですが、 null
を設定しておきます。
テンプレートパスには .\NullPath
を設定することにより、 ZipProject
を ProjectTemplates
に展開してくれます。
なお、この時 LanguageVsTemplate
には、 *.vstemplate
にて設定した ProjectType
と
同様の値を設定する必要があります。
次に HSPProjectFactory
を作成します。
using System; using System.Runtime.InteropServices; using Microsoft.VisualStudioTools.Project; using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider; namespace HSPToolsVS.Project { [Guid(HSPToolsConstants.ProjectFactoryGuid)] internal class HSPProjectFactory : ProjectFactory { private readonly CommonProjectPackage _package; public HSPProjectFactory(CommonProjectPackage package) : base((IServiceProvider) package) { _package = package; } #region Overrides of ProjectFactory internal override ProjectNode CreateProject() { var stream = GetType().Assembly.GetManifestResourceStream("HSPToolsVS.Project.Resources.imagelis.bmp"); var project = new HSPProjectNode(Site, Utilities.GetImageList(stream)); var package = ((IServiceProvider) _package).GetService(typeof(IOleServiceProvider)); project.SetSite((IOleServiceProvider) package); return project; } #endregion } }
普通に実装していきます。
注意点としては、 imagelis.bmp
は 埋め込みリソース
としておいてください。
次は HSPProjectNode
です。
using System; using System.Drawing; using System.IO; using System.Runtime.InteropServices; using System.Windows.Forms; using Microsoft.VisualStudioTools.Project; namespace HSPToolsVS.Project { [Guid(HSPToolsConstants.ProjectNodeGuid)] internal class HSPProjectNode : CommonProjectNode { public HSPProjectNode(IServiceProvider serviceProvider, ImageList imageList) : base(serviceProvider, imageList) { } #region Overrides of ProjectNode internal override string IssueTrackerUrl => "https://github.com/fuyuno/HSPToolsVS/issues"; protected sealed override Stream ProjectIconsImageStripStream { get { throw new NotSupportedException("HSP Tools does not support strip icons"); } } #endregion #region Overrides of CommonProjectNode public override Type GetProjectFactoryType() => typeof(HSPProjectFactory); public override Type GetEditorFactoryType() => null; public override string GetProjectName() => "HSP"; public override string GetFormatList() => "HSP Script Files(*.hsp,*.as)|*.hsp;*.as"; public override Type GetGeneralPropertyPageType() => null; public override Type GetLibraryManagerType() => null; public override IProjectLauncher GetLauncher() => null; #endregion } }
プロジェクトのアイテムにアイコンを設定する場合は、別途ソースを記述する必要がありますが、
今回は必要が無いので実装しません。
~そのうちやります。~
ここまでできたところで、 VS ExpInstance を起動すれば、新しいプロジェクトが追加され、
また Visual Studio で扱うことができるようになっていることが確認できると思います。
参考