Never run in-proc on .NET Core.
Sean Hall committed
Jun 3, 2020 at 12:31 UTC
be9b04d2272ef9a9e811d2d5486593b628a68993
10 files changed
+129
-29
appveyor.cmd
+3
@@ -19,6 +19,9 @@ dotnet publish -c %_C% -o %_P%\WixToolset.MSBuild\tools\net461\x64\ -f net461 -r
19
dotnet publish -c %_C% -o %_P%\WixToolset.MSBuild\tools\net461\x64\ -f net461 -r win-x64 src\wix
20
dotnet publish -c %_C% -o %_P%\WixToolset.MSBuild\tools\net461\x64\ -f net461 -r win-x64 src\wixcop
21
dotnet publish -c %_C% -o %_P%\WixToolset.MSBuild\tools\netcoreapp2.1\ -f netcoreapp2.1 src\WixToolset.BuildTasks
22
+dotnet publish -c %_C% -o %_P%\WixToolset.MSBuild\tools\netcoreapp2.1\ -f netcoreapp2.1 src\heat
23
+dotnet publish -c %_C% -o %_P%\WixToolset.MSBuild\tools\netcoreapp2.1\ -f netcoreapp2.1 src\wix
24
+dotnet publish -c %_C% -o %_P%\WixToolset.MSBuild\tools\netcoreapp2.1\ -f netcoreapp2.1 src\wixcop
25
dotnet publish -c %_C% -o %_P%\WixToolset.MSBuild\ src\WixToolset.MSBuild
26
27
dotnet pack -c %_C% src\dotnet-wix
src/WixToolset.BuildTasks/HeatTask_InProc.cs
+2
@@ -1,5 +1,6 @@
1
// 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.
2
3
+#if !NETCOREAPP
4
namespace WixToolset.BuildTasks
5
{
6
using WixToolset.Extensibility;
@@ -25,3 +26,4 @@ namespace WixToolset.BuildTasks
26
}
27
}
28
}
29
+#endif
src/WixToolset.BuildTasks/MsbuildMessageListener.cs
+2
@@ -1,5 +1,6 @@
1
// 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.
2
3
+#if !NETCOREAPP
4
namespace WixToolset.BuildTasks
5
{
6
using System;
@@ -64,3 +65,4 @@ namespace WixToolset.BuildTasks
65
public MessageLevel CalculateMessageLevel(IMessaging messaging, Message message, MessageLevel defaultMessageLevel) => defaultMessageLevel;
66
}
67
}
68
+#endif
src/WixToolset.BuildTasks/ToolsetTask.cs
+46
-3
@@ -4,10 +4,13 @@ namespace WixToolset.BuildTasks
4
{
5
using System;
6
using System.IO;
7
+ using System.Runtime.InteropServices;
8
using Microsoft.Build.Utilities;
9
10
public abstract partial class ToolsetTask : ToolTask
11
{
12
+ private static readonly string ThisDllPath = new Uri(typeof(ToolsetTask).Assembly.CodeBase).AbsolutePath;
13
+
14
/// <summary>
15
/// Gets or sets additional options that are appended the the tool command-line.
16
/// </summary>
@@ -53,6 +56,8 @@ namespace WixToolset.BuildTasks
56
/// </summary>
57
public bool VerboseOutput { get; set; }
58
59
+ private string ToolFullPath => Path.Combine(Path.GetDirectoryName(ThisDllPath), this.ToolExe);
60
+
61
/// <summary>
62
/// Get the path to the executable.
63
/// </summary>
@@ -63,13 +68,20 @@ namespace WixToolset.BuildTasks
68
/// </remarks>
69
protected sealed override string GenerateFullPathToTool()
70
{
66
- var thisDllPath = new Uri(typeof(ToolsetTask).Assembly.CodeBase).AbsolutePath;
71
+#if !NETCOREAPP
72
if (!this.RunAsSeparateProcess)
73
{
74
// We need to return a path that exists, so if we're not actually going to run the tool then just return this dll path.
70
- return thisDllPath;
75
+ return ThisDllPath;
76
}
72
- return Path.Combine(Path.GetDirectoryName(thisDllPath), this.ToolExe);
77
+ return this.ToolFullPath;
78
+#else
79
+ if (IsSelfExecutable(this.ToolFullPath, out var toolFullPath))
80
+ {
81
+ return toolFullPath;
82
+ }
83
+ return DotnetFullPath;
84
+#endif
85
}
86
87
protected sealed override string GenerateResponseFileCommands()
@@ -94,5 +106,36 @@ namespace WixToolset.BuildTasks
106
commandLineBuilder.AppendArrayIfNotNull("-wx ", this.TreatSpecificWarningsAsErrors);
107
commandLineBuilder.AppendIfTrue("-wx", this.TreatWarningsAsErrors);
108
}
109
+
110
+#if NETCOREAPP
111
+ private static readonly string DotnetFullPath = Environment.GetEnvironmentVariable("DOTNET_HOST_PATH") ?? "dotnet";
112
+
113
+ protected override string GenerateCommandLineCommands()
114
+ {
115
+ if (IsSelfExecutable(this.ToolFullPath, out var toolFullPath))
116
+ {
117
+ return null;
118
+ }
119
+ else
120
+ {
121
+ return $"exec \"{toolFullPath}\"";
122
+ }
123
+ }
124
+
125
+ private static bool IsSelfExecutable(string proposedToolFullPath, out string toolFullPath)
126
+ {
127
+ var toolFullPathWithoutExtension = Path.Combine(Path.GetDirectoryName(proposedToolFullPath), Path.GetFileNameWithoutExtension(proposedToolFullPath));
128
+ var exeExtension = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : String.Empty;
129
+ var exeToolFullPath = $"{toolFullPathWithoutExtension}{exeExtension}";
130
+ if (File.Exists(exeToolFullPath))
131
+ {
132
+ toolFullPath = exeToolFullPath;
133
+ return true;
134
+ }
135
+
136
+ toolFullPath = $"{toolFullPathWithoutExtension}.dll";
137
+ return false;
138
+ }
139
+#endif
140
}
141
}
src/WixToolset.BuildTasks/ToolsetTask_InProc.cs
+2
@@ -1,5 +1,6 @@
1
// 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.
2
3
+#if !NETCOREAPP
4
namespace WixToolset.BuildTasks
5
{
6
using System;
@@ -69,3 +70,4 @@ namespace WixToolset.BuildTasks
70
protected abstract string TaskShortName { get; }
71
}
72
}
73
+#endif
src/WixToolset.BuildTasks/WixBuild_InProc.cs
+2
@@ -1,5 +1,6 @@
1
// 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.
2
3
+#if !NETCOREAPP
4
namespace WixToolset.BuildTasks
5
{
6
using WixToolset.Data;
@@ -51,3 +52,4 @@ namespace WixToolset.BuildTasks
52
}
53
}
54
}
55
+#endif
src/WixToolset.BuildTasks/WixToolset.BuildTasks.csproj
+5
-6
@@ -18,19 +18,18 @@
18
</PropertyGroup>
19
20
<ItemGroup>
21
- <ProjectReference Include="..\WixToolset.Tools.Core\WixToolset.Tools.Core.csproj" />
21
+ <PackageReference Include="WixToolset.Dtf.WindowsInstaller" Version="4.0.*" />
22
</ItemGroup>
23
24
- <ItemGroup>
24
+ <ItemGroup Condition="'$(TargetFramework)'=='net461'">
25
+ <PackageReference Include="Microsoft.Build.Tasks.Core" Version="14.3" />
26
<PackageReference Include="WixToolset.Core.Burn" Version="4.0.*" />
27
<PackageReference Include="WixToolset.Core.WindowsInstaller" Version="4.0.*" />
27
- <PackageReference Include="WixToolset.Dtf.WindowsInstaller" Version="4.0.*" />
28
<PackageReference Include="WixToolset.Harvesters" Version="4.0.*" />
29
</ItemGroup>
30
31
- <ItemGroup>
32
- <PackageReference Include="Microsoft.Build.Tasks.Core" Version="14.3" Condition="'$(TargetFramework)'=='net461'" />
33
- <PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.7.179" Condition="'$(TargetFramework)'=='netcoreapp2.1' " />
31
+ <ItemGroup Condition="'$(TargetFramework)'=='netcoreapp2.1' ">
32
+ <PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.7.179" />
33
</ItemGroup>
34
35
<ItemGroup>
src/test/WixToolsetTest.MSBuild/MsbuildFixture.cs
+18
-12
@@ -12,6 +12,7 @@ namespace WixToolsetTest.MSBuild
12
public class MsbuildFixture
13
{
14
[Theory]
15
+ [InlineData(BuildSystem.DotNetCoreSdk)]
16
[InlineData(BuildSystem.MSBuild)]
17
[InlineData(BuildSystem.MSBuild64)]
18
public void CanBuildSimpleBundle(BuildSystem buildSystem)
@@ -44,6 +45,7 @@ namespace WixToolsetTest.MSBuild
45
}
46
47
[Theory]
48
+ [InlineData(BuildSystem.DotNetCoreSdk)]
49
[InlineData(BuildSystem.MSBuild)]
50
[InlineData(BuildSystem.MSBuild64)]
51
public void CanBuildSimpleMergeModule(BuildSystem buildSystem)
@@ -76,6 +78,7 @@ namespace WixToolsetTest.MSBuild
78
}
79
80
[Theory]
81
+ [InlineData(BuildSystem.DotNetCoreSdk)]
82
[InlineData(BuildSystem.MSBuild)]
83
[InlineData(BuildSystem.MSBuild64)]
84
public void CanBuildSimpleMsiPackage(BuildSystem buildSystem)
@@ -112,6 +115,7 @@ namespace WixToolsetTest.MSBuild
115
}
116
117
[Theory]
118
+ [InlineData(BuildSystem.DotNetCoreSdk)]
119
[InlineData(BuildSystem.MSBuild)]
120
[InlineData(BuildSystem.MSBuild64)]
121
public void CanBuildSimpleMsiPackageWithMergeModule(BuildSystem buildSystem)
@@ -145,6 +149,7 @@ namespace WixToolsetTest.MSBuild
149
}
150
151
[Theory]
152
+ [InlineData(BuildSystem.DotNetCoreSdk)]
153
[InlineData(BuildSystem.MSBuild)]
154
[InlineData(BuildSystem.MSBuild64)]
155
public void CanBuildWithDefaultAndExplicitlyFullWixpdbs(BuildSystem buildSystem)
@@ -161,6 +166,7 @@ namespace WixToolsetTest.MSBuild
166
}
167
168
[Theory]
169
+ [InlineData(BuildSystem.DotNetCoreSdk)]
170
[InlineData(BuildSystem.MSBuild)]
171
[InlineData(BuildSystem.MSBuild64)]
172
public void CanBuildWithNoWixpdb(BuildSystem buildSystem)
@@ -198,6 +204,7 @@ namespace WixToolsetTest.MSBuild
204
}
205
206
[Theory]
207
+ [InlineData(BuildSystem.DotNetCoreSdk)]
208
[InlineData(BuildSystem.MSBuild)]
209
[InlineData(BuildSystem.MSBuild64)]
210
public void CanBuild64BitMsiPackage(BuildSystem buildSystem)
@@ -234,6 +241,7 @@ namespace WixToolsetTest.MSBuild
241
}
242
243
[Theory(Skip = "Currently fails")]
244
+ [InlineData(BuildSystem.DotNetCoreSdk)]
245
[InlineData(BuildSystem.MSBuild)]
246
[InlineData(BuildSystem.MSBuild64)]
247
public void CanBuildSimpleMsiPackageWithIceSuppressions(BuildSystem buildSystem)
@@ -249,13 +257,14 @@ namespace WixToolsetTest.MSBuild
257
258
var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
259
{
252
- "-p:SuppressIces=\"ICE45;ICE46\"",
260
+ MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "SuppressIces", "ICE45;ICE46"),
261
});
262
result.AssertSuccess();
263
}
264
}
265
266
[Theory]
267
+ [InlineData(BuildSystem.DotNetCoreSdk)]
268
[InlineData(BuildSystem.MSBuild)]
269
[InlineData(BuildSystem.MSBuild64)]
270
public void CanBuildSimpleMsiPackageWithWarningSuppressions(BuildSystem buildSystem)
@@ -271,7 +280,7 @@ namespace WixToolsetTest.MSBuild
280
281
var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
282
{
274
- "-p:SuppressSpecificWarnings=\"1118;1102\"",
283
+ MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "SuppressSpecificWarnings", "1118;1102"),
284
});
285
result.AssertSuccess();
286
@@ -281,6 +290,8 @@ namespace WixToolsetTest.MSBuild
290
}
291
292
[Theory]
293
+ [InlineData(BuildSystem.DotNetCoreSdk, null)]
294
+ [InlineData(BuildSystem.DotNetCoreSdk, true)]
295
[InlineData(BuildSystem.MSBuild, null)]
296
[InlineData(BuildSystem.MSBuild, true)]
297
[InlineData(BuildSystem.MSBuild64, null)]
@@ -302,10 +313,8 @@ namespace WixToolsetTest.MSBuild
313
}, outOfProc: outOfProc);
314
result.AssertSuccess();
315
305
- var expectedOutOfProc = outOfProc.HasValue && outOfProc.Value;
306
- var expectedWixCommand = $"{(expectedOutOfProc ? "wix.exe" : "(wix.exe)")} build";
307
- var buildCommands = result.Output.Where(line => line.TrimStart().Contains(expectedWixCommand));
308
- Assert.Single(buildCommands);
316
+ var wixBuildCommands = MsbuildUtilities.GetToolCommandLines(result, "wix", "build", buildSystem, outOfProc);
317
+ Assert.Single(wixBuildCommands);
318
319
var path = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
320
.Select(s => s.Substring(baseFolder.Length + 1))
@@ -315,6 +324,7 @@ namespace WixToolsetTest.MSBuild
324
}
325
326
[Theory]
327
+ [InlineData(BuildSystem.DotNetCoreSdk)]
328
[InlineData(BuildSystem.MSBuild)]
329
[InlineData(BuildSystem.MSBuild64)]
330
public void CanBuildAndCleanSimpleMsiPackage(BuildSystem buildSystem)
@@ -328,10 +338,7 @@ namespace WixToolsetTest.MSBuild
338
var projectPath = Path.Combine(baseFolder, "MsiPackage.wixproj");
339
340
// Build
331
- var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
332
- {
333
- "-v:diag",
334
- });
341
+ var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, verbosityLevel: "diag");
342
result.AssertSuccess();
343
344
var buildOutput = String.Join("\r\n", result.Output);
@@ -346,8 +353,7 @@ namespace WixToolsetTest.MSBuild
353
result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
354
{
355
"-t:Clean",
349
- "-v:diag",
350
- });
356
+ }, verbosityLevel: "diag");
357
result.AssertSuccess();
358
359
var cleanOutput = String.Join("\r\n", result.Output);
src/test/WixToolsetTest.MSBuild/MsbuildHeatFixture.cs
+5
-6
@@ -3,6 +3,7 @@
3
namespace WixToolsetTest.MSBuild
4
{
5
using System;
6
+ using System.Collections.Generic;
7
using System.IO;
8
using System.Linq;
9
using WixBuildTools.TestSupport;
@@ -14,6 +15,7 @@ namespace WixToolsetTest.MSBuild
15
public class MsbuildHeatFixture
16
{
17
[Theory]
18
+ [InlineData(BuildSystem.DotNetCoreSdk)]
19
[InlineData(BuildSystem.MSBuild)]
20
[InlineData(BuildSystem.MSBuild64)]
21
public void CanBuildHeatFilePackage(BuildSystem buildSystem)
@@ -31,9 +33,7 @@ namespace WixToolsetTest.MSBuild
33
var result = MsbuildUtilities.BuildProject(buildSystem, projectPath);
34
result.AssertSuccess();
35
34
- var expectedOutOfProc = false;
35
- var expectedHeatCommand = $"{(expectedOutOfProc ? "heat.exe" : "(heat.exe)")} file";
36
- var heatCommandLines = result.Output.Where(line => line.Contains(expectedHeatCommand));
36
+ var heatCommandLines = MsbuildUtilities.GetToolCommandLines(result, "heat", "file", buildSystem);
37
Assert.Single(heatCommandLines);
38
39
var warnings = result.Output.Where(line => line.Contains(": warning"));
@@ -71,6 +71,7 @@ namespace WixToolsetTest.MSBuild
71
}
72
73
[Theory]
74
+ [InlineData(BuildSystem.DotNetCoreSdk)]
75
[InlineData(BuildSystem.MSBuild)]
76
[InlineData(BuildSystem.MSBuild64)]
77
public void CanBuildHeatFileWithMultipleFilesPackage(BuildSystem buildSystem)
@@ -88,9 +89,7 @@ namespace WixToolsetTest.MSBuild
89
var result = MsbuildUtilities.BuildProject(buildSystem, projectPath);
90
result.AssertSuccess();
91
91
- var expectedOutOfProc = false;
92
- var expectedHeatCommand = $"{(expectedOutOfProc ? "heat.exe" : "(heat.exe)")} file";
93
- var heatCommandLines = result.Output.Where(line => line.Contains(expectedHeatCommand));
92
+ var heatCommandLines = MsbuildUtilities.GetToolCommandLines(result, "heat", "file", buildSystem);
93
Assert.Equal(2, heatCommandLines.Count());
94
95
var warnings = result.Output.Where(line => line.Contains(": warning"));
src/test/WixToolsetTest.MSBuild/MsbuildUtilities.cs
+44
-2
@@ -5,10 +5,12 @@ namespace WixToolsetTest.MSBuild
5
using System;
6
using System.Collections.Generic;
7
using System.IO;
8
+ using System.Linq;
9
using WixBuildTools.TestSupport;
10
11
public enum BuildSystem
12
{
13
+ DotNetCoreSdk,
14
MSBuild,
15
MSBuild64,
16
}
@@ -17,12 +19,13 @@ namespace WixToolsetTest.MSBuild
19
{
20
public static readonly string WixPropsPath = Path.Combine(new Uri(typeof(MsbuildUtilities).Assembly.CodeBase).AbsolutePath, "..", "..", "publish", "WixToolset.MSBuild", "build", "WixToolset.MSBuild.props");
21
20
- public static MsbuildRunnerResult BuildProject(BuildSystem buildSystem, string projectPath, string[] arguments = null, string configuration = "Release", bool? outOfProc = null)
22
+ public static MsbuildRunnerResult BuildProject(BuildSystem buildSystem, string projectPath, string[] arguments = null, string configuration = "Release", bool? outOfProc = null, string verbosityLevel = "normal")
23
{
24
var allArgs = new List<string>
25
{
26
+ $"-verbosity:{verbosityLevel}",
27
$"-p:Configuration={configuration}",
25
- $"-p:WixMSBuildProps={MsbuildUtilities.WixPropsPath}",
28
+ GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildUtilities.WixPropsPath),
29
// Node reuse means that child msbuild processes can stay around after the build completes.
30
// Under that scenario, the root msbuild does not reliably close its streams which causes us to hang.
31
"-nr:false",
@@ -40,6 +43,16 @@ namespace WixToolsetTest.MSBuild
43
44
switch (buildSystem)
45
{
46
+ case BuildSystem.DotNetCoreSdk:
47
+ {
48
+ allArgs.Add(projectPath);
49
+ var result = DotnetRunner.Execute("msbuild", allArgs.ToArray());
50
+ return new MsbuildRunnerResult
51
+ {
52
+ ExitCode = result.ExitCode,
53
+ Output = result.StandardOutput,
54
+ };
55
+ }
56
case BuildSystem.MSBuild:
57
case BuildSystem.MSBuild64:
58
{
@@ -51,5 +64,34 @@ namespace WixToolsetTest.MSBuild
64
}
65
}
66
}
67
+
68
+ public static string GetQuotedPropertySwitch(BuildSystem buildSystem, string propertyName, string valueToQuote)
69
+ {
70
+ switch (buildSystem)
71
+ {
72
+ case BuildSystem.DotNetCoreSdk:
73
+ {
74
+ return $"-p:{propertyName}=\\\"{valueToQuote}\\\"";
75
+ }
76
+ case BuildSystem.MSBuild:
77
+ case BuildSystem.MSBuild64:
78
+ {
79
+ return $"-p:{propertyName}=\"{valueToQuote}\"";
80
+ }
81
+ default:
82
+ {
83
+ throw new NotImplementedException();
84
+ }
85
+ }
86
+ }
87
+
88
+ public static IEnumerable<string> GetToolCommandLines(MsbuildRunnerResult result, string toolName, string operation, BuildSystem buildSystem, bool? outOfProc = null)
89
+ {
90
+ var expectedOutOfProc = buildSystem == BuildSystem.DotNetCoreSdk || outOfProc.HasValue && outOfProc.Value;
91
+ var expectedToolExe = !expectedOutOfProc ? $"({toolName}.exe)" :
92
+ buildSystem == BuildSystem.DotNetCoreSdk ? $"{toolName}.dll\"" : $"{toolName}.exe";
93
+ var expectedToolCommand = $"{expectedToolExe} {operation}";
94
+ return result.Output.Where(line => line.Contains(expectedToolCommand));
95
+ }
96
}
97
}