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)' < '4.0' "
253
- Text="MSBuild v$(MSBuildToolsVersion) is not supported by the project "$(MSBuildProjectFile)". 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 "$(MSBuildProjectFile)". 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);