@joebigelow / wix-1 / commits / be9b04d2

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 }