開発備忘録

WPF(Xaml + C#)の話題を中心に.Net関連についてのブログです。

Jenkinsでインストーラーを作成する方法

Visual Studio 2012以降、昔ながらのインストーラセットアップ プロジェクトが拡張機能で使用することができます。
Visual Studio 2010は、Install Shield一択だったのですがあれは何だったのか…)
できればこのあたりもJenkinsで実行できれば、

ということができます。

まずは下準備としてJenkinsを起動しているPCのVisual Studio拡張機能からインストーラーを追加します。
[ツール] - [拡張機能と更新プログラム]を選択し、オンラインから"install"で検索してインストーラープロジェクトを追加します。
f:id:iyemon018:20170125193456p:plain

次にレジストリエディタを開いて以下の値を追加します。

  • HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\12.0_Config\MSBuild\EnableOutOfProcBuild
  • DWORD:0

f:id:iyemon018:20170125194627p:plain

"12.0_Config"と言うのは"Visual Studio 2013"の構成情報のことです。
2012の場合は、"11.0_Config"、2015の場合は、"14.0_Config"となっています。

ちなみに、これを追加しないとビルドしても以下のようなメッセージが出力されてインストーラーが作成されません。
(これに結構ハマってました…)

ERROR: An error occurred while validating.  HRESULT = '8000000A'

続いてJenkinsの設定です。
ジョブの設定から、"Windowsバッチコマンドの実行"を選択して以下のコマンドを入力します。

:: 開発環境によって実行フォルダを変えてください。
cd C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE
devenv "%WORKSPACE%<ソリューションファイルパス>" /Project "%WORKSPACE%<セットアッププロジェクトパス>" /Build "Release"

上記では"Release"モードでビルドしていますが、ここは必要に応じて変更してください。
なお、"devenv.exe"のコマンドライン引数は以下を参照してください。

Devenv コマンド ライン スイッチ

Jenkinsで独自NuGetパッケージの復元メモ

以前、Jenkinsを使用してNuGetパッケージを復元することができました。
iyemon018.hatenablog.com

今回は独自に作成したNuGetパッケージの復元を行います。
例えば社内で管理しているライブラリの復元も行うことができます。

まずは下準備

1. Jenkins実行ユーザーの"%AppData%\NuGet"フォルダから"NuGet.Config"を参照します。
2. ファイルを開き以下のように変更します。※1.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageRestore>
    <add key="enabled" value="True" />
    <add key="automatic" value="True" />
  </packageRestore>
  <packageSources>
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />
    <add key="<独自NuGet>" value="<独自NuGetパッケージ保存パス>" />
  </packageSources>
  <disabledPackageSources />
  <activePackageSource>
    <add key="All" value="(Aggregate source)" />
  </activePackageSource>
  <bindingRedirects>
    <add key="skip" value="False" />
  </bindingRedirects>
</configuration>

3. Jenkinsのジョブで"Windowsバッチコマンドの実行"を選択し、以下のコマンドを入力します。

cd "C:\Nuget"
nuget.exe restore %WORKSPACE%\<ソリューション ファイル パス>

※1. 以下の方法でもOKです。
1. NuGet.configを別名で保存し、任意のフォルダにコピーします。(内容は上記2.のものを保存します。)
2. Jenkinsのジョブで"Windowsバッチコマンドの実行"を選択肢、以下のコマンドを入力します。

cd "C:\Nuget"
nuget.exe restore %WORKSPACE%\<ソリューション ファイル パス> -configfile "<NuGet.configファイルパス>"

(NuGet.exeのコマンドライン引数については以下を参照)
NuGet Command-Line Interface (CLI) Reference | Microsoft Docs

独自NuGetパッケージが共有フォルダに配置されている場合は、アクセス権を持つユーザーで実行する必要があります。
Jenkinsの実行ユーザーを変更するには以下を参照してください。
iyemon018.hatenablog.com

Windows上のJenkinsを特定のユーザーで実行する

Windows上でJenkinsを起動しているときに実行しているユーザーを切り替える必要があったのでメモ。
環境は以下の通り。

JenkinsはWindows上ではサービスで起動していて、各ジョブはOSのシステムが実行しています。
試しにジョブで"Windowsバッチコマンドの実行"で以下のコマンドを入力します。

whoami /user

するとコンソール出力にこのようなログが出力されます。

ユーザー名          SID     
=================== ========
nt authority\system <SID>

これが現在Jenkinsを実行しているユーザーです。
このユーザーを切り替えるには、以下の手順を実行します。

  1. [コントロールパネル] - [管理ツール] - [サービス] を開く。
  2. 一覧から[Jenkins]を探し、右クリック[プロパティ]を選択する。
  3. [ログオン]タブから[アカウント]を選択し、ユーザーとパスワードを入力する。
  4. [OK]をクリックしてサービスを再起動する。

これで指定したユーザーで実行することができます。

JenkinsでNuGetパッケージの復元メモ

Jenkinsを使用してプロジェクトをビルドするとNuGetパッケージの復元が実行されなかったので、その解決方法をメモメモ
環境は以下の通り

Visual Studio 2015からはNuGet.exeがプロジェクトに配置されなくなり、ビルド時に自動的に復元されるようになったためJenkins側で復元してやる必要があります。

1.NuGet.exeをダウンロードする。

以下のページからNuGet.exeをダウンロードして任意の場所に保存します。
Installing NuGet | Microsoft Docs

2.Windowsバッチコマンドを実行する。

ジョブのビルドから[Windowsバッチコマンドの実行]を選択して以下のコマンドを設定します。

cd "<NuGet.exeの配置パス>"
nuget.exe restore "%WORKSPACE%<復元対象のソリューション ファイルパス>"

Visual Studio 2013以前は、プロジェクトに配置されているNuGet.exeを参照すればOKです。

これでジョブを実行すればパッケージの復元ができます。
復元のためのバッチコマンド実行は、必ずMSBuildの実行よりも前に設定してください。
また、NuGet.exeのオプションなどは以下を参照してください。
NuGet Command-Line Interface (CLI) Reference | Microsoft Docs

TFS構成DBからプロジェクト コレクション名を列挙する

またまたTFSネタです。
TFSのDBをバックアップする上で、プロジェクト コレクション名が必要だったのですが、TFSが現在管理しているプロジェクト コレクション名を全て取得する方法って無いのかな―と調べていました。
結果から言うとそれっぽい情報は無かったので、色々試してみた結果、以下の方法でそれっぽく取得することができました。

動作環境には"Team Foundation Server 2012"を使用しています。

まずは、SQL Server Management Studio を起動してTFSの管理しているインスタンスに接続します。
そこでクエリエディタを表示して以下のSQLクエリを入力して実行すると、TFSの持つリソース情報が表示されます。

SELECT * FROM [Tfs_Configuration].[dbo].[tbl_CatalogResource]

実行結果
f:id:iyemon018:20170111190710p:plain

”DisplayName”列にところどころプロジェクト コレクション名が見えるのですが、どうやって取得するか…
しばし悩んだところで、以下のテーブルに[Identifier]列の定義があったのでこれを使います。

SELECT * FROM [Tfs_Configuration].[dbo].[tbl_CatalogResourceType]

実行結果
f:id:iyemon018:20170111191024p:plain

上図の赤枠線で囲っているところがチーム プロジェクト コレクションのリソース識別子っぽいです。
では、以下のSQLを実行してみましょう。

SELECT * FROM [Tfs_Configuration].[dbo].[tbl_CatalogResource] WHERE [tbl_CatalogResource].[ResourceType]=<Identifier>

これでチーム プロジェクト コレクションの一覧を全て取得することができました。
tbl_CatalogResourceTypeテーブルの[Identifier]列は、リソース種別の識別子なのでtbl_CatalogResourceテーブルの[Identifier]列とは一致しません。
[ResourceType]列と比較することでリソースの種別を識別することが可能になっています。

TFS構成ツールを使用してコレクションのアタッチ/デタッチを実行する方法

今日もTFSネタです。
TFSには”TfsConfig.exe"という構成ツールが含まれていますが、これを使用してコマンドラインからプロジェクト コレクションのアタッチ/デタッチ/削除を行うことができます。

  • アタッチ
C:\Program Files\Microsoft Team Foundation Server 11.0\Tools>TfsConfig Collection /attach /CollectionName:<コレクション名> /CollectionDb:<インスタンス名>;<コレクションDB名>
  • デタッチ
C:\Program Files\Microsoft Team Foundation Server 11.0\Tools>TfsConfig Collection /detach /CollectionName:<コレクション名>
  • 削除
C:\Program Files\Microsoft Team Foundation Server 11.0\Tools>TfsConfig Collection /delete /CollectionName:<コレクション名>

デタッチと削除はコレクション名だけでいいですが、アタッチの場合はDB名も指定する必要があります。
DB名は、通常は"Tfs_<コレクション名>"で作成されているのでご確認を。

他にもコマンドラインからいろいろ制御できるので以下のURLを確認しながらバッチを書いてもいいかもしれません。
www.visualstudio.com

Team Foundation Serverデータベースの復元方法メモ

新年早々にサーバー機の新調に伴い、Team Foundation Serverのバックアップと復元を行ったのですが、かなり手こずったので手順をメモメモ
オチ的には、「TFS 管理コンソールのバックアップ・復元機能は使用しないほうがいい」ということでした。


使用する環境はこんな感じです。

バックアップサーバーを"サーバー A"、復元サーバーを"サーバー B"とします。
どちらも以下の環境を使用しています。

・OS:Windows Server 2012 R2
Team Foundation Server 2012 Update4
SQL Server 2012 Standard SP3

1. TFS 復元手順

  1. Team Foundation Server 管理コンソールから"サーバー A" の全てのプロジェクトコレクションを[停止]→[デタッチ]する。
  2. SQL Server Management Studio から上記のプロジェクトコレクションに該当するDBをバックアップする。(※1)
  3. "サーバー B"のTeam Foundation Server 管理コンソールから[インストール構成]-[詳細]を選択する。
  4. 構成(Tfs_Configuration)のみ作成し、"レポート"、"Share Point"、"デフォルトコレクション"は作成しない。
  5. "サーバー B"からSQL Server Management Studio を使用してバックアップしたDBを復元する。
  6. Team Foundation Server 管理コンソールの[チーム プロジェクト コレクション]-[コレクションのアタッチ]を選択して復元したDBへアタッチする。

この手順を実行してVS上でプロジェクトが表示されない場合は、【セキュリティの管理設定】でユーザーorグループを追加する。

※1.プロジェクトコレクションのDBは、"Tfs_プロジェクトコレクション名"という形式で作成されている。

2. セキュリティの管理設定

Team Foundation Server 管理コンソールからTFSのコレクション操作権限を設定するための機能です。
コレクション全体の設定は、[アプリケーション層]-[セキュリティの管理]から追加します。
コレクションごとの設定は、[チーム プロジェクト コレクション]-[コレクションを選択]-[セキュリティの管理]から追加します。

3. TFSの復元でうまく行かなかったこと

TFS 管理コンソールのバックアップ・復元機能を使用して復元を行う。

[現象]
まず、TFS 管理コンソールからバックアップすることは可能だった。
しかし、バックアップしたデータ(DB)を復元することができなかった。
復元を実行してもTFS 管理コンソールの[チーム プロジェクト コレクション]にはコレクションが表示されないが、SQL ServerにはDBが復元されているという現象が発生した。

[原因]
現時点では不明。
ログを見たりエラー番号で検索する限り、"DBの接続文字列が異なっている"や"SQL Serverインスタンス バージョンとDBバージョンが一致していないため"などが挙げられていた。
TFS のDBを見る限り、SQL Serverの接続文字列やTFSの構成情報を持っているので環境が変わるとそのあたりの情報が整合性が取れなくなっているのでは???

[対策]
上記の【復元手順】の通りに実行するとエラーが発生することなく実行できた。
TFS 管理コンソールのバックアップ・復元機能は使用せず、バッチでコレクションの停止、デタッチ、バックアップ、アタッチ、開始を行う必要がある。
このあたりはJenkinsなどのCIツールを使いたい。