インストールはVisual Studio Galleryから。 visualstudiogallery.msdn.microsoft.com
コードはGitHubで公開しています。 github.com
使い方はVisual Studio Galleryの方に載せていますが、ソリューションエクスプローラーでプロジェクトを右クリックして「CsProj Util」から3つのコマンドを実行できます。それぞれ、SolutionDir という定義をPropertyGroupに定義するもの、HintPathをSolutionDirに変換するもの、Config Transformを追加するもの、です。
そもそも作った経緯ですが、いくつかの理由でVS2015にした後に、生成したcsprojを編集したいことが増えました。VSのデフォルト機能でcsprojを編集するには、いったんプロジェクトをアンロードする必要があって面倒だなあということで、編集したいパターンごとにcsprojを編集するコマンドを用意した拡張を作りました。
SolutionDir プロパティの追加
SolutionDir というプロパティがVS2013までは定義されていたのが、2015からはなくなってしまいました*1。通常はなくても問題ないのかもしれませんが、次の HintPath の定義をする部分などで必要なケースが出てきたので、プロパティを追加するコマンドを用意しました。
HintPathを SolutionDir を用いたパスに変換
次のHintPathの変換ですが、HintPathはNugetでライブラリを参照に追加すると、ダウンロードしたライブラリへの参照がcsprojに追加され、そのパスがHintPathに追加されます。パスは通常
<HintPath>..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll</HintPath>
のように相対パスで定義されます。この相対パスは通常 csproj がある場所を基準に解釈されるため、csprojの1つ上のディレクトリ、つまりslnファイルがあるディレクトリの中のpackagesフォルダ以下を参照します。デフォルトの設定だと Nugetはslnファイルがあるフォルダの中にpackagesフォルダを作り、その中にダウンロードしたライブラリを配置するので問題ありません。 が、場合によってはcsprojがslnファイルの1つ下のフォルダには存在しない状況があってそのときに困ります。
一つの例が、あるソリューション Aに属するプロジェクトAが別のソリューション Libに属するLib プロジェクトをプロジェクトとして参照しているとします。そして、A.sln というフォルダの中に Libというフォルダがあり、その中にLib.sln が入っているとします*2。
フォルダA ├フォルダpackages ├A.sln ├フォルダA │├A.csproj │└packages.config └フォルダLib ├Lib.sln └フォルダLib ├Lib.csproj └packages.config
この場合、Lib.csproj は Lib.sln ではなく、A.sln に追加しています。そのため、Lib.csproj が必要なNugetライブラリは、A.slnと同じ場所にあるpackagesフォルダに格納されるため、 ../packages
という一つ上のフォルダを見てもライブラリは存在しません。そこで、相対パスの替わりに SolutionDir を明示的に外部から指定するものとして、そこを基準にdllのパスを定義するように変換する機能を作りました。先ほどのHintPathの例だとこうなります。
<HintPath>$(SolutionDir)\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll</HintPath>
そもそも Lib.csproj をNugetで配布すればこういうソリューション構成にならないのでは?という疑問もあるかと思いますが、この辺は弊社の開発の方針にあわせた構成になっています。このあたりの経緯は、「Build Insider MEETUP with Grani 第1回」のセッションレポートの中の「グラニのフレームワーク」に書いています。
Config変換の追加
Config変換の追加ですが、これはConsole アプリ向けの機能です。ASP.NET Webプロジェクトですと、Web.config をビルド構成およびデプロイ先に応じて変換することができます。それと同じことをConsoleアプリでも行いたいのですが、ビルド構成による変換であればいくつかのVS拡張が機能を提供しています。しかし、弊社ではコードそのものはビルド構成に依存しないものの、配置先に合わせたConfigを複数(最大10を超えるくらい)切り替えて展開したいケースが出てきました。この状況でビルド構成に応じた変換を使うと、ビルド構成が10も追加されて非常に扱いづらくなってしまいます。そこで、ビルド構成ではなく別のBuildTargetというプロパティをMSBuildで指定して、App.
最後に
project ファイルを任意に編集したいのであれば、この拡張機能が便利です。プロジェクトを開いたまま一時ファイルを作成してVSのテキストエディタとして編集できて、保存のタイミングでprojectを読み込み直してくれます。
EditProj: Visual Studio extension to edit project files - Ed's personal blog