1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
namespace WixBuildTools.TestSupport
{
using System;
using System.Collections.Generic;
using System.IO;
public class MsbuildRunner : ExternalExecutable
{
private static readonly string VswhereFindArguments = "-property installationPath -version [17.0,18.0)";
private static readonly string MsbuildCurrentRelativePath = @"MSBuild\Current\Bin\MSBuild.exe";
private static readonly string MsbuildCurrentRelativePath64 = @"MSBuild\Current\Bin\amd64\MSBuild.exe";
private static readonly object InitLock = new object();
private static bool Initialized;
private static MsbuildRunner MsbuildCurrentRunner;
private static MsbuildRunner MsbuildCurrentRunner64;
public static MsbuildRunnerResult Execute(string projectPath, string[] arguments = null, bool x64 = false) =>
InitAndExecute(String.Empty, projectPath, arguments, x64);
public static MsbuildRunnerResult ExecuteWithMsbuildCurrent(string projectPath, string[] arguments = null, bool x64 = false) =>
InitAndExecute("Current", projectPath, arguments, x64);
private static MsbuildRunnerResult InitAndExecute(string msbuildVersion, string projectPath, string[] arguments, bool x64)
{
lock (InitLock)
{
if (!Initialized)
{
Initialized = true;
var vswhereResult = VswhereRunner.Execute(VswhereFindArguments, true);
if (vswhereResult.ExitCode != 0)
{
throw new InvalidOperationException($"Failed to execute vswhere.exe, exit code: {vswhereResult.ExitCode}. Output:\r\n{String.Join("\r\n", vswhereResult.StandardOutput)}");
}
string msbuildCurrentPath = null;
string msbuildCurrentPath64 = null;
foreach (var installPath in vswhereResult.StandardOutput)
{
if (msbuildCurrentPath == null)
{
var path = Path.Combine(installPath, MsbuildCurrentRelativePath);
if (File.Exists(path))
{
msbuildCurrentPath = path;
}
}
if (msbuildCurrentPath64 == null)
{
var path = Path.Combine(installPath, MsbuildCurrentRelativePath64);
if (File.Exists(path))
{
msbuildCurrentPath64 = path;
}
}
}
if (msbuildCurrentPath != null)
{
MsbuildCurrentRunner = new MsbuildRunner(msbuildCurrentPath);
}
if (msbuildCurrentPath64 != null)
{
MsbuildCurrentRunner64 = new MsbuildRunner(msbuildCurrentPath64);
}
}
}
MsbuildRunner runner = x64 ? MsbuildCurrentRunner64 : MsbuildCurrentRunner;
if (runner == null)
{
throw new InvalidOperationException($"Failed to find an installed{(x64 ? " 64-bit" : String.Empty)} MSBuild{msbuildVersion}");
}
return runner.ExecuteCore(projectPath, arguments);
}
private MsbuildRunner(string exePath) : base(exePath) { }
private MsbuildRunnerResult ExecuteCore(string projectPath, string[] arguments)
{
var total = new List<string>
{
projectPath,
};
if (arguments != null)
{
total.AddRange(arguments);
}
var args = CombineArguments(total);
var mergeErrorIntoOutput = true;
var workingFolder = Path.GetDirectoryName(projectPath);
var result = this.Run(args, mergeErrorIntoOutput, workingFolder);
return new MsbuildRunnerResult
{
ExitCode = result.ExitCode,
Output = result.StandardOutput,
};
}
}
}
|