Created
May 26, 2016 09:06
-
-
Save devlights/55056735ff291e80f2575fca0a1354c8 to your computer and use it in GitHub Desktop.
C#からMsBuildをコードで実行 (Microsoft.Build名前空間, BuildManager)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| namespace Samples.MsBuildExec | |
| { | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Diagnostics; | |
| using System.IO; | |
| using System.Linq; | |
| using System.Threading; | |
| using System.Threading.Tasks; | |
| using Microsoft.Build.BuildEngine; | |
| using Microsoft.Build.Evaluation; | |
| using Microsoft.Build.Execution; | |
| using Microsoft.Build.Framework; | |
| /// <summary> | |
| /// アプリケーションメインクラスです。 | |
| /// </summary> | |
| internal class Program | |
| { | |
| /// <summary> | |
| /// アプリケーションメインエントリポイントです。 | |
| /// </summary> | |
| internal static void Main() | |
| { | |
| new Program().Execute().Wait(); | |
| Utils.WriteLine("なにかキーを押すと終了します...."); | |
| Utils.WaitUserInput(); | |
| } | |
| /// <summary> | |
| /// 処理を実行します。 | |
| /// </summary> | |
| /// <returns> | |
| /// <see cref="Task" />オブジェクト | |
| /// </returns> | |
| /// <exception cref="Exception"> | |
| /// 処理中にエラーが発生した場合 | |
| /// </exception> | |
| internal async Task Execute() | |
| { | |
| // | |
| // MsBuildをコードから実行する場合 | |
| // 予め以下のDLLを参照設定しておく必要がある。 | |
| // ・Microsoft.Build.dll | |
| // ・Microsoft.Build.Engine.dll | |
| // ・Microsoft.Build.Framework.dll | |
| // | |
| // | |
| // 結果フォルダ作成 | |
| // | |
| var destDir = DateTime.Now.ToString("yyyyMMddHHmmss"); | |
| Utils.CreateResultDirectory(destDir); | |
| var cursorLeft = 0; | |
| var cursorTop = 0; | |
| var startBuildSignal = new ManualResetEventSlim(); | |
| var cancelSource = new CancellationTokenSource(); | |
| var cancelToken = cancelSource.Token; | |
| // | |
| // 処理中をコンソールに表示するためのタスク | |
| // ビルドが開始されたタイミングでこのタスクも出力を初める | |
| // | |
| var showProcessingMarkTask = Task.Run( | |
| async () => | |
| { | |
| startBuildSignal.Wait(cancelToken); | |
| do | |
| { | |
| if (cancelToken.IsCancellationRequested) | |
| { | |
| break; | |
| } | |
| Utils.SetCursorPosition(cursorLeft, cursorTop); | |
| Utils.Write("★★処理中★★"); | |
| await Task.Delay(TimeSpan.FromSeconds(1), cancelToken); | |
| if (cancelToken.IsCancellationRequested) | |
| { | |
| break; | |
| } | |
| Utils.SetCursorPosition(cursorLeft, cursorTop); | |
| Utils.Write(" "); | |
| await Task.Delay(TimeSpan.FromSeconds(1), cancelToken); | |
| } | |
| while (true); | |
| }, | |
| cancelToken); | |
| // | |
| // ビルドを実行するタスク | |
| // | |
| var buildTask = Task.Run( | |
| () => | |
| { | |
| // | |
| // ビルド時の構成をマップで指定 | |
| // | |
| var prop = new Dictionary<string, string>(); | |
| prop.Add("Configuration", Utils.MsBuildConfiguration); | |
| prop.Add("Platform", Utils.MsBuildPlatform); | |
| // | |
| // ビルドリクエストを構築 | |
| // | |
| var targets = Utils.MsBuildTargets.Split(new[] { "," }, StringSplitOptions.None); | |
| var request = new BuildRequestData(Utils.SlnFilePath, prop, null, targets, null); | |
| // | |
| // ビルドパラメータを構築 | |
| // パラメータ構築時にログファイル設定が行える | |
| // | |
| var projCollection = new ProjectCollection(); | |
| var parameter = new BuildParameters(projCollection); | |
| parameter.Loggers = new List<ILogger> { new FileLogger { Parameters = Utils.MsBuildLogFileName } }; | |
| Utils.Write("ビルド開始...."); | |
| Interlocked.Exchange(ref cursorLeft, Utils.CursorLeft); | |
| Interlocked.Exchange(ref cursorTop, Utils.CursorTop); | |
| startBuildSignal.Set(); | |
| // | |
| // 最後にビルド実行を行ってくれるManagerオブジェクトを取得し、ビルド実行 | |
| // | |
| var manager = BuildManager.DefaultBuildManager; | |
| var result = manager.Build(parameter, request); | |
| // | |
| // 結果はOverallResultプロパティで判定できる | |
| // | |
| if (result.OverallResult == BuildResultCode.Failure) | |
| { | |
| Utils.WriteLine(string.Empty); | |
| Utils.WriteLine("ビルド失敗"); | |
| if (result.Exception != null) | |
| { | |
| Utils.WriteLine(result.Exception.ToString()); | |
| throw result.Exception; | |
| } | |
| throw new Exception("ビルドに失敗しました。"); | |
| } | |
| Utils.WriteLine(string.Empty); | |
| Utils.WriteLine("ビルド終了...."); | |
| }); | |
| try | |
| { | |
| await buildTask; | |
| try | |
| { | |
| cancelSource.Cancel(); | |
| await showProcessingMarkTask; | |
| } | |
| catch (TaskCanceledException) | |
| { | |
| // noop | |
| } | |
| } | |
| catch (Exception ex) | |
| { | |
| Utils.WriteLine("★★★★★ 処理中にエラーが発生しました ★★★★★"); | |
| Utils.WriteLine(ex.ToString()); | |
| cancelSource.Cancel(); | |
| return; | |
| } | |
| // 出力先をオープン | |
| Process.Start(destDir); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment