@joebigelow / wix-1 / commits / 82a26a32

Add ability for net461 tasks to run the tool out of proc.

Sean Hall committed Jun 1, 2020 at 21:58 UTC 82a26a321bae36e38743f50f38887387a392ce24
9 files changed +126 -49
appveyor.cmd
+7 -3
@@ -9,11 +9,15 @@ dotnet test -c %_C% src\test\WixToolsetTest.BuildTasks
9 dotnet test -c %_C% src\test\WixToolsetTest.WixCop
10
11 dotnet publish -c %_C% -o %_P%\dotnet-wix\ -f netcoreapp2.1 src\wix
12 -@rem dotnet publish -c %_C% -o %_P%\netfx-heat\ -f net461 src\heat
13 -@rem dotnet publish -c %_C% -o %_P%\netfx-wix\ -f net461 src\wix
14 -@rem dotnet publish -c %_C% -o %_P%\netfx-wixcop\ -f net461 src\wixcop
12 +
13 dotnet publish -c %_C% -o %_P%\WixToolset.MSBuild\tools\net461\x86\ -f net461 -r win-x86 src\WixToolset.BuildTasks
14 +dotnet publish -c %_C% -o %_P%\WixToolset.MSBuild\tools\net461\x86\ -f net461 -r win-x86 src\heat
15 +dotnet publish -c %_C% -o %_P%\WixToolset.MSBuild\tools\net461\x86\ -f net461 -r win-x86 src\wix
16 +dotnet publish -c %_C% -o %_P%\WixToolset.MSBuild\tools\net461\x86\ -f net461 -r win-x86 src\wixcop
17 dotnet publish -c %_C% -o %_P%\WixToolset.MSBuild\tools\net461\x64\ -f net461 -r win-x64 src\WixToolset.BuildTasks
18 +dotnet publish -c %_C% -o %_P%\WixToolset.MSBuild\tools\net461\x64\ -f net461 -r win-x64 src\heat
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\ src\WixToolset.MSBuild
23
src/WixToolset.BuildTasks/HeatTask.cs
+4 -5
@@ -59,7 +59,8 @@ namespace WixToolset.BuildTasks
59 set { this.transforms = value; }
60 }
61
62 - protected override string TaskShortName => "HEAT";
62 + protected sealed override string TaskShortName => "HEAT";
63 + protected sealed override string ToolName => "heat.exe";
64
65 /// <summary>
66 /// Gets the name of the heat operation performed by the task.
@@ -71,10 +72,8 @@ namespace WixToolset.BuildTasks
72 get;
73 }
74
74 - protected override void ExecuteCore(IWixToolsetServiceProvider serviceProvider, IMessageListener listener, string commandLineString)
75 + protected sealed override int ExecuteCore(IWixToolsetServiceProvider serviceProvider, IMessageListener listener, string commandLineString)
76 {
76 - this.Log.LogMessage(MessageImportance.Normal, "heat.exe " + commandLineString);
77 -
77 var messaging = serviceProvider.GetService<IMessaging>();
78 messaging.SetListener(listener);
79
@@ -83,7 +82,7 @@ namespace WixToolset.BuildTasks
82
83 var commandLine = HeatCommandLineFactory.CreateCommandLine(serviceProvider, true);
84 var command = commandLine.ParseStandardCommandLine(arguments);
86 - command?.Execute();
85 + return command?.Execute() ?? -1;
86 }
87
88 /// <summary>
src/WixToolset.BuildTasks/ToolsetTask.cs
+66 -10
@@ -3,14 +3,16 @@
3 namespace WixToolset.BuildTasks
4 {
5 using System;
6 + using System.IO;
7 using System.Runtime.InteropServices;
8 + using Microsoft.Build.Framework;
9 using Microsoft.Build.Utilities;
10 using WixToolset.Core;
11 using WixToolset.Data;
12 using WixToolset.Extensibility;
13 using WixToolset.Extensibility.Services;
14
13 - public abstract class ToolsetTask : Task
15 + public abstract class ToolsetTask : ToolTask
16 {
17 /// <summary>
18 /// Gets or sets additional options that are appended the the tool command-line.
@@ -26,6 +28,12 @@ namespace WixToolset.BuildTasks
28 /// </summary>
29 public bool NoLogo { get; set; }
30
31 + /// <summary>
32 + /// Gets or sets a flag indicating whether the task
33 + /// should be run as separate process or in-proc.
34 + /// </summary>
35 + public bool RunAsSeparateProcess { get; set; }
36 +
37 /// <summary>
38 /// Gets or sets whether all warnings should be suppressed.
39 /// </summary>
@@ -51,19 +59,27 @@ namespace WixToolset.BuildTasks
59 /// </summary>
60 public bool VerboseOutput { get; set; }
61
54 - public override bool Execute()
62 + protected sealed override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands)
63 {
56 - var serviceProvider = WixToolsetServiceProviderFactory.CreateServiceProvider();
64 + if (this.RunAsSeparateProcess)
65 + {
66 + return base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands);
67 + }
68 +
69 + return this.ExecuteInProc($"{commandLineCommands} {responseFileCommands}");
70 + }
71
72 + private int ExecuteInProc(string commandLineString)
73 + {
74 + this.Log.LogMessage(MessageImportance.Normal, $"({this.ToolName}){commandLineString}");
75 +
76 + var serviceProvider = WixToolsetServiceProviderFactory.CreateServiceProvider();
77 var listener = new MsbuildMessageListener(this.Log, this.TaskShortName, this.BuildEngine.ProjectFileOfTaskNode);
78 + int exitCode = -1;
79
80 try
81 {
62 - var commandLineBuilder = new WixCommandLineBuilder();
63 - this.BuildCommandLine(commandLineBuilder);
64 -
65 - var commandLineString = commandLineBuilder.ToString();
66 - this.ExecuteCore(serviceProvider, listener, commandLineString);
82 + exitCode = this.ExecuteCore(serviceProvider, listener, commandLineString);
83 }
84 catch (WixException e)
85 {
@@ -79,7 +95,47 @@ namespace WixToolset.BuildTasks
95 }
96 }
97
82 - return !this.Log.HasLoggedErrors;
98 + if (exitCode == 0 && this.Log.HasLoggedErrors)
99 + {
100 + exitCode = -1;
101 + }
102 + return exitCode;
103 + }
104 +
105 + /// <summary>
106 + /// Get the path to the executable.
107 + /// </summary>
108 + /// <remarks>
109 + /// ToolTask only calls GenerateFullPathToTool when the ToolPath property is not set.
110 + /// WiX never sets the ToolPath property, but the user can through $(WixToolDir).
111 + /// If we return only a file name, ToolTask will search the system paths for it.
112 + /// </remarks>
113 + protected sealed override string GenerateFullPathToTool()
114 + {
115 + var thisDllPath = new Uri(typeof(ToolsetTask).Assembly.CodeBase).AbsolutePath;
116 + if (this.RunAsSeparateProcess)
117 + {
118 + return Path.Combine(Path.GetDirectoryName(thisDllPath), this.ToolExe);
119 + }
120 +
121 + // 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.
122 + return thisDllPath;
123 + }
124 +
125 + protected sealed override string GenerateResponseFileCommands()
126 + {
127 + var commandLineBuilder = new WixCommandLineBuilder();
128 + this.BuildCommandLine(commandLineBuilder);
129 + return commandLineBuilder.ToString();
130 + }
131 +
132 + protected sealed override void LogToolCommand(string message)
133 + {
134 + // Only log this if we're actually going to do it.
135 + if (this.RunAsSeparateProcess)
136 + {
137 + base.LogToolCommand(message);
138 + }
139 }
140
141 /// <summary>
@@ -98,7 +154,7 @@ namespace WixToolset.BuildTasks
154 commandLineBuilder.AppendIfTrue("-wx", this.TreatWarningsAsErrors);
155 }
156
101 - protected abstract void ExecuteCore(IWixToolsetServiceProvider serviceProvider, IMessageListener messageListener, string commandLineString);
157 + protected abstract int ExecuteCore(IWixToolsetServiceProvider serviceProvider, IMessageListener messageListener, string commandLineString);
158
159 protected abstract string TaskShortName { get; }
160 }
src/WixToolset.BuildTasks/WixBuild.cs
+3 -7
@@ -4,10 +4,7 @@ namespace WixToolset.BuildTasks
4 {
5 using System;
6 using System.Collections.Generic;
7 - using System.Runtime.InteropServices;
7 using Microsoft.Build.Framework;
9 - using Microsoft.Build.Utilities;
10 - using WixToolset.Core;
8 using WixToolset.Data;
9 using WixToolset.Extensibility;
10 using WixToolset.Extensibility.Data;
@@ -80,11 +77,10 @@ namespace WixToolset.BuildTasks
77 public string AdditionalCub { get; set; }
78
79 protected override string TaskShortName => "WIX";
80 + protected override string ToolName => "wix.exe";
81
84 - protected override void ExecuteCore(IWixToolsetServiceProvider serviceProvider, IMessageListener listener, string commandLineString)
82 + protected override int ExecuteCore(IWixToolsetServiceProvider serviceProvider, IMessageListener listener, string commandLineString)
83 {
86 - this.Log.LogMessage(MessageImportance.Normal, "wix.exe " + commandLineString);
87 -
84 var messaging = serviceProvider.GetService<IMessaging>();
85 messaging.SetListener(listener);
86
@@ -95,7 +91,7 @@ namespace WixToolset.BuildTasks
91 commandLine.ExtensionManager = this.CreateExtensionManagerWithStandardBackends(serviceProvider, messaging, arguments.Extensions);
92 commandLine.Arguments = arguments;
93 var command = commandLine.ParseStandardCommandLine();
98 - command?.Execute();
94 + return command?.Execute() ?? -1;
95 }
96
97 protected override void BuildCommandLine(WixCommandLineBuilder commandLineBuilder)
src/WixToolset.MSBuild/tools/wix.harvest.targets
+16 -3
@@ -3,6 +3,10 @@
3
4
5 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
6 + <!-- These properties can be overridden to support non-default installations. -->
7 + <PropertyGroup>
8 + <HeatToolDir Condition=" '$(HeatToolDir)' == '' ">$(WixToolDir)</HeatToolDir>
9 + </PropertyGroup>
10
11 <!-- These tasks are extensions for harvesting WiX source code from other sources. -->
12 <UsingTask TaskName="HeatFile" AssemblyFile="$(WixTasksPath)" />
@@ -274,7 +278,10 @@
278 Configuration="%(_AllHeatProjects.Configuration)"
279 Platform="%(_AllHeatProjects.Platform)"
280 GenerateWixVariables="$(HarvestProjectsGenerateWixVariables)"
277 - AdditionalOptions="$(HarvestProjectsAdditionalOptions)">
281 + AdditionalOptions="$(HarvestProjectsAdditionalOptions)"
282 + RunAsSeparateProcess="$(RunWixToolsOutOfProc)"
283 + ToolExe="$(HeatToolExe)"
284 + ToolPath="$(HeatToolDir)">
285
286 <Output TaskParameter="OutputFile" ItemName="Compile" />
287 <Output TaskParameter="OutputFile" ItemName="FileWrites" />
@@ -359,7 +366,10 @@
366 SuppressCom="%(HarvestDirectory.SuppressCom)"
367 SuppressRootDirectory="%(HarvestDirectory.SuppressRootDirectory)"
368 SuppressRegistry="%(HarvestDirectory.SuppressRegistry)"
362 - AdditionalOptions="$(HarvestDirectoryAdditionalOptions)">
369 + AdditionalOptions="$(HarvestDirectoryAdditionalOptions)"
370 + RunAsSeparateProcess="$(RunWixToolsOutOfProc)"
371 + ToolExe="$(HeatToolExe)"
372 + ToolPath="$(HeatToolDir)">
373
374 <Output TaskParameter="OutputFile" ItemName="Compile" />
375 <Output TaskParameter="OutputFile" ItemName="FileWrites" />
@@ -432,7 +442,10 @@
442 SuppressCom="%(HarvestFile.SuppressCom)"
443 SuppressRegistry="%(HarvestFile.SuppressRegistry)"
444 SuppressRootDirectory="%(HarvestFile.SuppressRootDirectory)"
435 - AdditionalOptions="$(HarvestFileAdditionalOptions)">
445 + AdditionalOptions="$(HarvestFileAdditionalOptions)"
446 + RunAsSeparateProcess="$(RunWixToolsOutOfProc)"
447 + ToolExe="$(HeatToolExe)"
448 + ToolPath="$(HeatToolDir)">
449
450 <Output TaskParameter="OutputFile" ItemName="Compile" />
451 <Output TaskParameter="OutputFile" ItemName="FileWrites" />
src/WixToolset.MSBuild/tools/wix.targets
+5 -6
@@ -249,11 +249,6 @@
249
250 <Error
251 Code="WIX102"
252 - Condition=" '$(MSBuildToolsVersion)' == '' OR '$(MSBuildToolsVersion)' &lt; '4.0' "
253 - Text="MSBuild v$(MSBuildToolsVersion) is not supported by the project &quot;$(MSBuildProjectFile)&quot;. You must use MSBuild v4.0 or later." />
254 -
255 - <Error
256 - Code="WIX103"
252 Condition=" '$(WixPdbType)' != 'none' and '$(WixPdbType)' != 'full' "
253 Text="The WixPdbType property '$(WixPdbType)' is not valid in project &quot;$(MSBuildProjectFile)&quot;. Supported values are: 'full', 'none'" />
254
@@ -695,7 +690,11 @@
690
691 SuppressValidation="$(SuppressValidation)"
692 SuppressIces="$(SuppressIces)"
698 - AdditionalCub="$(AdditionalCub)" />
693 + AdditionalCub="$(AdditionalCub)"
694 +
695 + RunAsSeparateProcess="$(RunWixToolsOutOfProc)"
696 + ToolExe="$(WixToolExe)"
697 + ToolPath="$(WixToolDir)" />
698
699 <!--
700 SuppressAllWarnings="$(CompilerSuppressAllWarnings);$(LinkerSuppressAllWarnings)"
src/test/WixToolsetTest.MSBuild/MsbuildFixture.cs
+13 -12
@@ -28,9 +28,6 @@ namespace WixToolsetTest.MSBuild
28 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath);
29 result.AssertSuccess();
30
31 - var platformSwitches = result.Output.Where(line => line.TrimStart().StartsWith("wix.exe build -platform x86"));
32 - Assert.Single(platformSwitches);
33 -
31 var warnings = result.Output.Where(line => line.Contains(": warning"));
32 Assert.Empty(warnings);
33
@@ -63,9 +60,6 @@ namespace WixToolsetTest.MSBuild
60 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath);
61 result.AssertSuccess();
62
66 - var platformSwitches = result.Output.Where(line => line.TrimStart().StartsWith("wix.exe build -platform x86"));
67 - Assert.Single(platformSwitches);
68 -
63 var warnings = result.Output.Where(line => line.Contains(": warning"));
64 Assert.Empty(warnings);
65
@@ -98,7 +92,7 @@ namespace WixToolsetTest.MSBuild
92 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath);
93 result.AssertSuccess();
94
101 - var platformSwitches = result.Output.Where(line => line.TrimStart().StartsWith("wix.exe build -platform x86"));
95 + var platformSwitches = result.Output.Where(line => line.Contains("-platform x86"));
96 Assert.Single(platformSwitches);
97
98 var warnings = result.Output.Where(line => line.Contains(": warning"));
@@ -223,7 +217,7 @@ namespace WixToolsetTest.MSBuild
217 });
218 result.AssertSuccess();
219
226 - var platformSwitches = result.Output.Where(line => line.TrimStart().StartsWith("wix.exe build -platform x64"));
220 + var platformSwitches = result.Output.Where(line => line.Contains("-platform x64"));
221 Assert.Single(platformSwitches);
222
223 var paths = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
@@ -287,9 +281,11 @@ namespace WixToolsetTest.MSBuild
281 }
282
283 [Theory]
290 - [InlineData(BuildSystem.MSBuild)]
291 - [InlineData(BuildSystem.MSBuild64)]
292 - public void CanBuildSimpleMsiPackageAsWixipl(BuildSystem buildSystem)
284 + [InlineData(BuildSystem.MSBuild, null)]
285 + [InlineData(BuildSystem.MSBuild, true)]
286 + [InlineData(BuildSystem.MSBuild64, null)]
287 + [InlineData(BuildSystem.MSBuild64, true)]
288 + public void CanBuildSimpleMsiPackageAsWixipl(BuildSystem buildSystem, bool? outOfProc)
289 {
290 var sourceFolder = TestData.Get(@"TestData\SimpleMsiPackage\MsiPackage");
291
@@ -303,9 +299,14 @@ namespace WixToolsetTest.MSBuild
299 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
300 {
301 "-p:OutputType=IntermediatePostLink",
306 - });
302 + }, outOfProc: outOfProc);
303 result.AssertSuccess();
304
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);
309 +
310 var path = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
311 .Select(s => s.Substring(baseFolder.Length + 1))
312 .Single();
src/test/WixToolsetTest.MSBuild/MsbuildHeatFixture.cs
+6 -2
@@ -31,7 +31,9 @@ namespace WixToolsetTest.MSBuild
31 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath);
32 result.AssertSuccess();
33
34 - var heatCommandLines = result.Output.Where(line => line.TrimStart().StartsWith("heat.exe file"));
34 + var expectedOutOfProc = false;
35 + var expectedHeatCommand = $"{(expectedOutOfProc ? "heat.exe" : "(heat.exe)")} file";
36 + var heatCommandLines = result.Output.Where(line => line.Contains(expectedHeatCommand));
37 Assert.Single(heatCommandLines);
38
39 var warnings = result.Output.Where(line => line.Contains(": warning"));
@@ -86,7 +88,9 @@ namespace WixToolsetTest.MSBuild
88 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath);
89 result.AssertSuccess();
90
89 - var heatCommandLines = result.Output.Where(line => line.TrimStart().StartsWith("heat.exe file"));
91 + var expectedOutOfProc = false;
92 + var expectedHeatCommand = $"{(expectedOutOfProc ? "heat.exe" : "(heat.exe)")} file";
93 + var heatCommandLines = result.Output.Where(line => line.Contains(expectedHeatCommand));
94 Assert.Equal(2, heatCommandLines.Count());
95
96 var warnings = result.Output.Where(line => line.Contains(": warning"));
src/test/WixToolsetTest.MSBuild/MsbuildUtilities.cs
+6 -1
@@ -17,7 +17,7 @@ namespace WixToolsetTest.MSBuild
17 {
18 public static readonly string WixPropsPath = Path.Combine(new Uri(typeof(MsbuildUtilities).Assembly.CodeBase).AbsolutePath, "..", "..", "publish", "WixToolset.MSBuild", "build", "WixToolset.MSBuild.props");
19
20 - public static MsbuildRunnerResult BuildProject(BuildSystem buildSystem, string projectPath, string[] arguments = null, string configuration = "Release")
20 + public static MsbuildRunnerResult BuildProject(BuildSystem buildSystem, string projectPath, string[] arguments = null, string configuration = "Release", bool? outOfProc = null)
21 {
22 var allArgs = new List<string>
23 {
@@ -28,6 +28,11 @@ namespace WixToolsetTest.MSBuild
28 "-nr:false",
29 };
30
31 + if (outOfProc.HasValue)
32 + {
33 + allArgs.Add($"-p:RunWixToolsOutOfProc={outOfProc.Value}");
34 + }
35 +
36 if (arguments != null)
37 {
38 allArgs.AddRange(arguments);