kazuk は null に触れてしまった

C# / .NET 系技術ネタ縛りでお送りしております

タグアーカイブ: Project Template

Multi Project な Project Template を作成する


元ネタは

How to: Create Multi-Project Templates
http://msdn.microsoft.com/en-us/library/ms185308.aspx

なんだけど、一回作ってる最中にうまくビルドできなくなったので、メモとりながら「やってみる」という blog

要 Visual Studio SDK です。

プロジェクトテンプレートのプロジェクトを作成。ソリューションエクスプローラー上での構造があうように作る。

imageimage

<?xml version="1.0" encoding="utf-8"?>
<VSTemplate Version="3.0.0" 
            Type="ProjectGroup"
            xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
  <TemplateData>
    <Name>LibWithUnitTest</Name>
    <Description>&lt;No description available&gt;</Description>
    <Icon>LibWithUnitTest.ico</Icon>
    <ProjectType>CSharp</ProjectType>
    <RequiredFrameworkVersion>2.0</RequiredFrameworkVersion>
    <SortOrder>1000</SortOrder>
    <TemplateID>526730eb-c930-4614-8398-64a21c9f008a</TemplateID>
    <CreateNewFolder>true</CreateNewFolder>
    <DefaultName>LibWithUnitTest</DefaultName>
    <ProvideDefaultName>true</ProvideDefaultName>
  </TemplateData>
  <TemplateContent>
    <ProjectCollection>
      <ProjectTemplateLink ProjectName="Implementation">
        ClassLibrary\ClassLibrary.vstemplate
      </ProjectTemplateLink>
      <ProjectTemplateLink ProjectName="UnitTest">
        UnitTest\UnitTest.vstemplate
      </ProjectTemplateLink>
    </ProjectCollection>
  </TemplateContent>
</VSTemplate>

あれ、ビルドできた。(ぉぃ

んでプロジェクトの追加したら普通にできた。(ぉぃ

 

企画倒れ!

…となぜ最初のは失敗したのかなと。 .cs のファイルプロパティで、ビルドアクションは「なし」にしてないと駄目。子プロジェクト側 vstemplate のビルドアクションは「なし」にした方が良いみたい。(VSTemplate ビルドアクションになってるとその分 Project Template の zipが吐かれますね)って事で、ファイルプロパティの設定間違ってるだけでした。

imageimage

っていう感じですね。

ってここまで書いてからこんなの見つけちゃった。

Multi-Project Templates with Wizard: Visual Studio 2010 Sample

http://vsix.codeplex.com/

プロジェクト作成時の Wizard まで実装してるね!コッチでも子プロジェクトの vstemplateのビルドアクションは無しになってますね。

http://vsix.codeplex.com/SourceControl/changeset/view/61761#1354286

<ItemGroup> <None Include="Children\Windows Library\ProjectTemplate.vstemplate" /> </ItemGroup>

ほら、無し(None)でしょ。

広告

Visual Studio プロジェクトテンプレートの作り方


NuGet のプロジェクトテンプレートを公開してたりする人なので、レシピを公開しておきましょう。

最も簡単な方法は Visual Studio のファイルメニューからテンプレートの作成なんですが、今回はちっと難しい方法を。

Visual Studio SDK をインストールします。Download details: Visual Studio 2010 SDK

こいつをインストールすると、プロジェクトの種類として Extensibility が選べるようになり、Visual Studio の拡張パッケージを作成したり色々できる他に、その他色々のおまけがついてます。

image

今回は ASP.NET MVC3 のHttpModule を作成する為のプロジェクトテンプレートを書いてみます。プロジェクト名を設定して出てくる画面はこんな感じ。

image

いきなり vstemplate が開かれてますね。ソリューションエクスプローラーでの表示にはProjectTemplate.csproj 含め幾つかファイルが入ってますね。

というわけで、目的に応じて「あとは好きに致したまえ(ぇ」なんで、ASP.NET MVC3で使うHttpModuleの作成に使うテンプレートになるようにカスタムしていきます。

まず、Class1.cs で最初にできるべきコードを考える為に、本物を作ってみましょう。

クラスライブラリプロジェクトを追加して、そこの上で HttpModule を作るための作業をします。

image

System.Web とかを参照設定して

image

Class1.csをHttpModule1.csにリネームして IHttpModuleを派生して実装するのに十分な事をやります。

IHttpModule.DisposeのDisposeパターンを実装してやばそうなら Debug.Fail を呼ぶぐらいをデバッグ版でやるまでが今回想定できる範囲でしょうか。

image

ビルドしてちゃんとビルドできると解ったら、いきなり作ったクラスライブラリプロジェクトをアンロードします。

ソリューションエクスプローラーからプロジェクトのコンテキストメニューから「プロジェクトのアンロード」を選びます。

アンロードしたプロジェクトを右クリックで編集を選ぶと csproj の編集になります。(が見るだけで編集するわけではありません)

これを ProjectTemplate.csproj と並べたのがこんな感じ。

image

後はこの両者を比べながらProjectTemplate.csprojが「いい感じになるようにします(ぉぃ」ここでビルドシーケンスに仕込みとかができますね。NuGetパッケージプロジェクトの時はここで仕込みを入れました。(ちょっとだけ後述)

まぁ、参照設定の Reference の所が一番とっつき良いでしょうね。(MVC3入ってないじゃん、うん、裏でインストールやってて止まる罠にはまった為、単純にASP.NET HttpModuleのプロジェクトになってる)

いい感じになったらプロジェクトのコンテンツに行きましょう。

今回は HttpModule1.cs がコンテンツになりますのでコンテンツになるようにまた左右に並べて「いい感じになるようにします(ぉぃ」

image

こんな感じに。

$safeprojectname$ とかの暗号めいた物のリファレンスはこちら。

テンプレート名 ($if$ とかのドキュメントが無いように感じるのは自分だけでしょうか?)

お気づきかもですが、 NuGet の Configuration File and Source-Code Transformations がこの $で記号を挟む形式って事で、NuGetはVS内にあるテンプレート機構にオンラインリポジトリを結びつけた物という見方も出来たりするかもしれませんね。

んでこれをビルドするとプロジェクトテンプレートの zip ファイルが bin/構成 配下に吐き出されます。

これを自分の ドキュメントの Visual Studio 2010\Templates 配下の適切な場所に配置するとそれをベースとしてプロジェクトを作る事ができるようになります。

もともとビルド成功してた物を参考に「いい感じになるようにします(ぉぃ」だったので、プロジェクトを作ってみてビルドできない様であればなんかが間違ってるって事ですね。

csprojでのビルドシーケンスへの仕込みをする時の Tips

Visual Studio は結構激しく csproj と関連依存ファイルをキャッシュするので、csprojへの仕込みとデバッグは大変です。MSBuildのImportを使って分離した編集用ファイルを見るようにしておいてそれを編集しながらビルドを試すとかはこのキャッシュ機構によって、いくら編集して保存しても反映されない事になり「直したのに直らない→何がわるいのか解らない→挫折しちゃってもいいかなモードがひたすら上昇」の負帰還ループにはまります。

「csprojへの仕込みのデバッグは Visual Studio ではできない」これを最初に前提として進みましょう。

プロジェクトのアンロードをして csproj の編集に入ったら、スタートメニューから Visual Studio のコマンドプロンプトを開き、cd プロジェクトのフォルダで msbuild をコマンドプロンプトから叩けるようにしておいて(これをやってくれるVS拡張は色々あります) csproj を編集して保存したらビルドはコマンドプロンプトから実行します。ビルドがいい感じでできるようになるまではこの状況で進むのがおすすめです。

csproj内では msbuild のTaskやTargetを書く事になりますが、Visual Studio 2010 では MsBuild 4.0 の BeforeTarget/AfterTargetによって既存の Microsoft.Common.Tagets に手を入れずにシーケンスの途中に割り込めるようになりました。この機能の効果は結構絶大で MsBuild インラインタスクとかと組み合わせるとビルドシーケンスは結構思うがままです。(参考: MsBuild 4.0の新機能でビルド時コード生成とか)

注意事項ですが最終的にいい感じな csproj を作ったらテキストの複製を取って Visual Studio に csproj を再読み込みさせてすぐにアンロードして再度編集に入って比較するのがおすすめです。Visual Studioは自分に都合の悪い記述をデフォルト値に戻す動きを暗黙にやります。このようなVisual Studioによって削除されたりデフォルト値に戻された値についてはVisual Studioでのビルド、デバッグに支障がでない何らかの方策を実施する必要な項目として重要な情報ですが比較してみないことには解らないというのが結構厄介です。(この動作についてはMsBuild とVSの連携に関するところにドキュメントで書いてあった記憶はありますが見つからない…)

作ったプロジェクトテンプレートを NuGet 配布しちゃうぞ

って手前味噌ですが、自分の流した NuGetPackageProject を取ってください、とり方はNuGet パッケージプロジェクトテンプレートを参照。

するとNuGetパッケージの為のプロジェクトを作れます、これを作ってるソリューションに追加します。

image

プロジェクトテンプレートプロジェクトの出力、今回は bin\Debug\ に作成されている Mvc3HttpModuleProject.zip を Tools 配下に置くようにします。

今回はパッケージプロジェクトのビルド前イベントでcopy コマンドを使いました。

image

Package/content 配下に readme.htm を作ります。(本来的にはいらないんですが、何もないとinstall.ps1が動かないので)

image image

ソリューション配下の packages\NuGetPackageProject\Tools\install.ps1 からプロジェクトテンプレートへのコピー操作を取ってきて Package\Tools\install.ps1 に貼り付けます。(うわ、install.ps1が動かねーってデバッグしてた時のまんまになってる)

param($installPath, $toolsPath, $package, $project)

Copy-Item $toolsPath\*.zip -destination ([System.Environment]::ExpandEnvironmentVariables("%VisualStudioDir%\Templates\ProjectTemplates\Visual C#\"))Write-Host "Project Template installed"

って感じでどうでしょう。

NuGetPackage.tt を編集して好みの nuspec を書いてビルドすると貴方のプロジェクトテンプレートを配布する nupkg がめでたく出来上がったはずです。

ローカルリポジトリを使ってテストして後は nuget.org に流すだけです。アカウントとってアカウント承認してもらったらさっくり放流です。

ローカルリポジトリからの一連のあたりは neue cc – NuGetパッケージの作り方、或いはXmlエディタとしてのVisual Studio が詳しく書いてるのでそちらをどうぞ。

という訳で Visual Studio プロジェクトテンプレートの作り方からcsprojへの仕込み tips 、手前味噌の NuGet パッケージ作成の仕方でした。

NuGet パッケージプロジェクトテンプレート


日本最速?

ってわけで NuGet パッケージを作るためのプロジェクトテンプレートをインストールしてくれる NuGet パッケージを作ってNuGet.org に放り込んでみました。

インストールスクリプトを使ってるんでコンソールから入れろって言われます。

image

おとなしくコンソールから行ってください(お願いします)。

イカ、コンソールでのコマンドとレスポンスでゲソ。

以下と変換しようとしたらイカが出たので侵略されたゲソ。太字が入力ゲソ。

PM> Get-Help NuGet
TOPIC
    about_NuGet
   
SHORT DESCRIPTION
    Provides information about NuGet Package Manager commands.
          
LONG DESCRIPTION
    This topic describes the NuGet Package Manager commands. NuGet is an integrated package
management tool for adding libraries and tools to .NET projects.

                
The following NuGet Cmdlets for are included.

Cmdlet Description
—————— ———————————————-
Get-Package Lists the set of packages available from the package source.

List-Package An alias for Get-Package. This is the more widely used command
for listing packages.

Install-Package Installs a package and its dependencies into the project.

Uninstall-Package Uninstalls a package. If other packages depend on this package,
the command will fail unless the –Force option is specified.

Update-Package Updates a package and its dependencies to a newer version.

New-Package Creates a new package when supplied with a Nuspec package specification file.

Add-BindingRedirects Examines all assemblies within the output path for a project and adds binding
redirects to the application (or web) configuration file where necessary.
                           
Get-Project Returns a reference to the DTE (Development Tools Environment) for the active
or specified project.

SEE ALSO
    Online documentation: http://go.microsoft.com/fwlink/?LinkID=206619
    Get-Package
    Install-Package
    Uninstall-Package
    Update-Package
    New-Package
PM>

dir ‘C:\Users\kikuchi\Documents\Visual Studio 2010\Templates\ProjectTemplates\Visual C#’
PM> List-Package -Remote -Filter NuGet

Id                                    Version                               Description                         
—                                    ——-                               ———–                         
NuGet.CommandLine                     1.0.11220.26                          NuGet command line tool used to cr…
NuGet.CommandLine                     1.1.2113.118                          NuGet command line tool used to cr…
NuGet.CommandLine                     1.1.2120.134                          NuGet command line tool used to cr…
NuGet.CommandLine                     1.1.2120.136                          NuGet command line tool used to cr…
NuGet.CommandLine                     1.1.2121.140                          NuGet command line tool used to cr…
Nuget.Core                            1.0.1120.104                          NuGet.Core is the core framework a…
NuGetPackageProject                   0.1.0                                 Customized build for NuGet pack.    
WebActivator                          1.0.0.0                               A NuGet package that allows other …

 

PM> Install-Package NuGetPackageProject
Successfully installed ‘NuGetPackageProject 0.1.0’
Successfully added ‘NuGetPackageProject 0.1.0’ to MvcApplication1
Installing Project Template! not executing now
PM> dir ‘C:\Users\kikuchi\Documents\Visual Studio 2010\Templates\ProjectTemplates\Visual C#’

    ディレクトリ: C:\Users\kikuchi\Documents\Visual Studio 2010\Templates\ProjectTemplates\Visual C#

Mode                LastWriteTime     Length Name                                                               
—-                ————-     —— —-                                                               
-a—        2011/01/21     17:52     103760 NuGetPackageProject.zip                                            

PM>

ってわけで、個人の ProjectTemplates に NuGetPackageProject.zip が追加されてるんで後はプロジェクトを追加する事の NuGetPackageProject を選ぶ。

image

NuGetPackage.tt が現れるので編集して説明その他を足す。

image

ソリューションエクスプローラーで適当にファイルを放り込むなりなんなりしてから華麗にビルド

image

ビルド成功ってわけ。

bin\Debug bin\Release に nupkg ができるので、nuget.org にポイするなり、社内のローカルパッケージリポジトリに放り込むと作業完了ですね。

ってわけで、このパッケージもこのパッケージで作られておりますな自己再帰的関係をむにゃむにゃやってみました。

パッケージ開発の注意事項

Install.ps1 / Uninstall.ps1 は Contents が空だと動きません。(これで結構はまりました。)

ローカルリポジトリを使ってインストール動作等は確認しましょう。

ディレクトリ構造はかなり決め打ちされてますので NuGet のドキュメントをよく読みましょう。

インストールスクリプトを使うと UI でのインストールはできなくなります。