summaryrefslogtreecommitdiff
path: root/src/tools/WixToolset.HeatTasks
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/tools/WixToolset.HeatTasks/HeatDirectory.cs47
-rw-r--r--src/tools/WixToolset.HeatTasks/HeatFile.cs44
-rw-r--r--src/tools/WixToolset.HeatTasks/HeatProject.cs (renamed from src/wix/WixToolset.BuildTasks/HeatProject.cs)56
-rw-r--r--src/tools/WixToolset.HeatTasks/HeatTask.cs176
-rw-r--r--src/tools/WixToolset.HeatTasks/RefreshBundleGeneratedFile.cs (renamed from src/wix/WixToolset.BuildTasks/RefreshBundleGeneratedFile.cs)57
-rw-r--r--src/tools/WixToolset.HeatTasks/RefreshGeneratedFile.cs (renamed from src/wix/WixToolset.BuildTasks/RefreshGeneratedFile.cs)52
-rw-r--r--src/tools/WixToolset.HeatTasks/RefreshTask.cs59
-rw-r--r--src/tools/WixToolset.HeatTasks/WixCommandLineBuilder.cs56
-rw-r--r--src/tools/WixToolset.HeatTasks/WixToolset.HeatTasks.csproj17
9 files changed, 450 insertions, 114 deletions
diff --git a/src/tools/WixToolset.HeatTasks/HeatDirectory.cs b/src/tools/WixToolset.HeatTasks/HeatDirectory.cs
new file mode 100644
index 00000000..8a169055
--- /dev/null
+++ b/src/tools/WixToolset.HeatTasks/HeatDirectory.cs
@@ -0,0 +1,47 @@
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
3namespace WixToolset.HeatTasks
4{
5 using Microsoft.Build.Framework;
6
7 public sealed class HeatDirectory : HeatTask
8 {
9 public string ComponentGroupName { get; set; }
10
11 [Required]
12 public string Directory { get; set; }
13
14 public string DirectoryRefId { get; set; }
15
16 public bool KeepEmptyDirectories { get; set; }
17
18 public string PreprocessorVariable { get; set; }
19
20 public bool SuppressCom { get; set; }
21
22 public bool SuppressRootDirectory { get; set; }
23
24 public bool SuppressRegistry { get; set; }
25
26 public string Template { get; set; }
27
28 protected override string OperationName => "dir";
29
30 protected override void BuildCommandLine(WixCommandLineBuilder commandLineBuilder)
31 {
32 commandLineBuilder.AppendSwitch(this.OperationName);
33 commandLineBuilder.AppendFileNameIfNotNull(this.Directory);
34
35 commandLineBuilder.AppendSwitchIfNotNull("-cg ", this.ComponentGroupName);
36 commandLineBuilder.AppendSwitchIfNotNull("-dr ", this.DirectoryRefId);
37 commandLineBuilder.AppendIfTrue("-ke", this.KeepEmptyDirectories);
38 commandLineBuilder.AppendIfTrue("-scom", this.SuppressCom);
39 commandLineBuilder.AppendIfTrue("-sreg", this.SuppressRegistry);
40 commandLineBuilder.AppendIfTrue("-srd", this.SuppressRootDirectory);
41 commandLineBuilder.AppendSwitchIfNotNull("-template ", this.Template);
42 commandLineBuilder.AppendSwitchIfNotNull("-var ", this.PreprocessorVariable);
43
44 base.BuildCommandLine(commandLineBuilder);
45 }
46 }
47}
diff --git a/src/tools/WixToolset.HeatTasks/HeatFile.cs b/src/tools/WixToolset.HeatTasks/HeatFile.cs
new file mode 100644
index 00000000..83cbc4d1
--- /dev/null
+++ b/src/tools/WixToolset.HeatTasks/HeatFile.cs
@@ -0,0 +1,44 @@
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
3namespace WixToolset.HeatTasks
4{
5 using Microsoft.Build.Framework;
6
7 public sealed class HeatFile : HeatTask
8 {
9 public string ComponentGroupName { get; set; }
10
11 public string DirectoryRefId { get; set; }
12
13 [Required]
14 public string File { get; set; }
15
16 public string PreprocessorVariable { get; set; }
17
18 public bool SuppressCom { get; set; }
19
20 public bool SuppressRegistry { get; set; }
21
22 public bool SuppressRootDirectory { get; set; }
23
24 public string Template { get; set; }
25
26 protected override string OperationName => "file";
27
28 protected override void BuildCommandLine(WixCommandLineBuilder commandLineBuilder)
29 {
30 commandLineBuilder.AppendSwitch(this.OperationName);
31 commandLineBuilder.AppendFileNameIfNotNull(this.File);
32
33 commandLineBuilder.AppendSwitchIfNotNull("-cg ", this.ComponentGroupName);
34 commandLineBuilder.AppendSwitchIfNotNull("-dr ", this.DirectoryRefId);
35 commandLineBuilder.AppendIfTrue("-scom", this.SuppressCom);
36 commandLineBuilder.AppendIfTrue("-srd", this.SuppressRootDirectory);
37 commandLineBuilder.AppendIfTrue("-sreg", this.SuppressRegistry);
38 commandLineBuilder.AppendSwitchIfNotNull("-template ", this.Template);
39 commandLineBuilder.AppendSwitchIfNotNull("-var ", this.PreprocessorVariable);
40
41 base.BuildCommandLine(commandLineBuilder);
42 }
43 }
44}
diff --git a/src/wix/WixToolset.BuildTasks/HeatProject.cs b/src/tools/WixToolset.HeatTasks/HeatProject.cs
index 3833a754..d54f6ad1 100644
--- a/src/wix/WixToolset.BuildTasks/HeatProject.cs
+++ b/src/tools/WixToolset.HeatTasks/HeatProject.cs
@@ -1,64 +1,29 @@
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. 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 2
3namespace WixToolset.BuildTasks 3namespace WixToolset.HeatTasks
4{ 4{
5 using Microsoft.Build.Framework; 5 using Microsoft.Build.Framework;
6 6
7 public sealed class HeatProject : HeatTask 7 public sealed class HeatProject : HeatTask
8 { 8 {
9 private string configuration;
10 private string directoryIds;
11 private string generateType;
12 private bool generateWixVariables;
13 private string platform;
14 private string project;
15 private string projectName;
16 private string[] projectOutputGroups; 9 private string[] projectOutputGroups;
17 10
18 public string Configuration 11 public string Configuration { get; set; }
19 {
20 get { return this.configuration; }
21 set { this.configuration = value; }
22 }
23 12
24 public string DirectoryIds 13 public string DirectoryIds { get; set; }
25 {
26 get { return this.directoryIds; }
27 set { this.directoryIds = value; }
28 }
29 14
30 public bool GenerateWixVariables 15 public bool GenerateWixVariables { get; set; }
31 {
32 get { return this.generateWixVariables; }
33 set { this.generateWixVariables = value; }
34 }
35 16
36 public string GenerateType 17 public string GenerateType { get; set; }
37 {
38 get { return this.generateType; }
39 set { this.generateType = value; }
40 }
41 18
42 public string MsbuildBinPath { get; set; } 19 public string MsbuildBinPath { get; set; }
43 20
44 public string Platform 21 public string Platform { get; set; }
45 {
46 get { return this.platform; }
47 set { this.platform = value; }
48 }
49 22
50 [Required] 23 [Required]
51 public string Project 24 public string Project { get; set; }
52 {
53 get { return this.project; }
54 set { this.project = value; }
55 }
56 25
57 public string ProjectName 26 public string ProjectName { get; set; }
58 {
59 get { return this.projectName; }
60 set { this.projectName = value; }
61 }
62 27
63 public string[] ProjectOutputGroups 28 public string[] ProjectOutputGroups
64 { 29 {
@@ -81,10 +46,7 @@ namespace WixToolset.BuildTasks
81 46
82 public bool UseToolsVersion { get; set; } 47 public bool UseToolsVersion { get; set; }
83 48
84 protected override string OperationName 49 protected override string OperationName => "project";
85 {
86 get { return "project"; }
87 }
88 50
89 protected override void BuildCommandLine(WixCommandLineBuilder commandLineBuilder) 51 protected override void BuildCommandLine(WixCommandLineBuilder commandLineBuilder)
90 { 52 {
diff --git a/src/tools/WixToolset.HeatTasks/HeatTask.cs b/src/tools/WixToolset.HeatTasks/HeatTask.cs
new file mode 100644
index 00000000..8942a7e1
--- /dev/null
+++ b/src/tools/WixToolset.HeatTasks/HeatTask.cs
@@ -0,0 +1,176 @@
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
3namespace WixToolset.HeatTasks
4{
5 using System;
6 using System.IO;
7 using System.Runtime.InteropServices;
8 using Microsoft.Build.Framework;
9 using Microsoft.Build.Utilities;
10
11 /// <summary>
12 /// A base MSBuild task to run the WiX harvester.
13 /// Specific harvester tasks should extend this class.
14 /// </summary>
15 public abstract partial class HeatTask : ToolTask
16 {
17 private static readonly string ThisDllPath = new Uri(typeof(HeatTask).Assembly.CodeBase).AbsolutePath;
18
19 /// <summary>
20 /// Gets or sets additional options that are appended the the tool command-line.
21 /// </summary>
22 /// <remarks>
23 /// This allows the task to support extended options in the tool which are not
24 /// explicitly implemented as properties on the task.
25 /// </remarks>
26 public string AdditionalOptions { get; set; }
27
28 /// <summary>
29 /// Gets or sets whether to display the logo.
30 /// </summary>
31 public bool NoLogo { get; set; }
32
33 /// <summary>
34 /// Gets or sets whether all warnings should be suppressed.
35 /// </summary>
36 public bool SuppressAllWarnings { get; set; }
37
38 /// <summary>
39 /// Gets or sets a list of specific warnings to be suppressed.
40 /// </summary>
41 public string[] SuppressSpecificWarnings { get; set; }
42
43 /// <summary>
44 /// Gets or sets whether all warnings should be treated as errors.
45 /// </summary>
46 public bool TreatWarningsAsErrors { get; set; }
47
48 /// <summary>
49 /// Gets or sets a list of specific warnings to treat as errors.
50 /// </summary>
51 public string[] TreatSpecificWarningsAsErrors { get; set; }
52
53 /// <summary>
54 /// Gets or sets whether to display verbose output.
55 /// </summary>
56 public bool VerboseOutput { get; set; }
57
58 public bool AutogenerateGuids { get; set; }
59
60 public bool GenerateGuidsNow { get; set; }
61
62 [Required]
63 [Output]
64 public ITaskItem OutputFile { get; set; }
65
66 public bool SuppressFragments { get; set; }
67
68 public bool SuppressUniqueIds { get; set; }
69
70 public string[] Transforms { get; set; }
71
72 protected sealed override string ToolName => "heat.exe";
73
74 /// <summary>
75 /// Gets the name of the heat operation performed by the task.
76 /// </summary>
77 /// <remarks>This is the first parameter passed on the heat.exe command-line.</remarks>
78 /// <value>The name of the heat operation performed by the task.</value>
79 protected abstract string OperationName { get; }
80
81 private string ToolFullPath
82 {
83 get
84 {
85 if (String.IsNullOrEmpty(this.ToolPath))
86 {
87 return Path.Combine(Path.GetDirectoryName(ThisDllPath), this.ToolExe);
88 }
89
90 return Path.Combine(this.ToolPath, this.ToolExe);
91 }
92 }
93
94 /// <summary>
95 /// Get the path to the executable.
96 /// </summary>
97 /// <remarks>
98 /// ToolTask only calls GenerateFullPathToTool when the ToolPath property is not set.
99 /// WiX never sets the ToolPath property, but the user can through $(HeatToolDir).
100 /// If we return only a file name, ToolTask will search the system paths for it.
101 /// </remarks>
102 protected sealed override string GenerateFullPathToTool()
103 {
104#if NETCOREAPP
105 // If we're not using heat.exe, use dotnet.exe to exec heat.dll.
106 // See this.GenerateCommandLine() where "exec heat.dll" is added.
107 if (!IsSelfExecutable(this.ToolFullPath, out var toolFullPath))
108 {
109 return DotnetFullPath;
110 }
111
112 return toolFullPath;
113#else
114 return this.ToolFullPath;
115#endif
116 }
117
118 protected sealed override string GenerateCommandLineCommands()
119 {
120 var commandLineBuilder = new WixCommandLineBuilder();
121
122#if NETCOREAPP
123 // If we're using dotnet.exe as the target executable, see this.GenerateFullPathToTool(),
124 // then add "exec heat.dll" to the beginning of the command-line.
125 if (!IsSelfExecutable(this.ToolFullPath, out var toolFullPath))
126 {
127 //commandLineBuilder.AppendSwitchIfNotNull("exec ", toolFullPath);
128 commandLineBuilder.AppendSwitch($"exec \"{toolFullPath}\"");
129 }
130#endif
131
132 this.BuildCommandLine(commandLineBuilder);
133 return commandLineBuilder.ToString();
134 }
135
136 /// <summary>
137 /// Builds a command line from options in this task.
138 /// </summary>
139 protected virtual void BuildCommandLine(WixCommandLineBuilder commandLineBuilder)
140 {
141 commandLineBuilder.AppendIfTrue("-nologo", this.NoLogo);
142 commandLineBuilder.AppendArrayIfNotNull("-sw", this.SuppressSpecificWarnings);
143 commandLineBuilder.AppendIfTrue("-sw", this.SuppressAllWarnings);
144 commandLineBuilder.AppendIfTrue("-v", this.VerboseOutput);
145 commandLineBuilder.AppendArrayIfNotNull("-wx", this.TreatSpecificWarningsAsErrors);
146 commandLineBuilder.AppendIfTrue("-wx", this.TreatWarningsAsErrors);
147
148 commandLineBuilder.AppendIfTrue("-ag", this.AutogenerateGuids);
149 commandLineBuilder.AppendIfTrue("-gg", this.GenerateGuidsNow);
150 commandLineBuilder.AppendIfTrue("-sfrag", this.SuppressFragments);
151 commandLineBuilder.AppendIfTrue("-suid", this.SuppressUniqueIds);
152 commandLineBuilder.AppendArrayIfNotNull("-t ", this.Transforms);
153 commandLineBuilder.AppendTextIfNotNull(this.AdditionalOptions);
154 commandLineBuilder.AppendSwitchIfNotNull("-out ", this.OutputFile);
155 }
156
157#if NETCOREAPP
158 private static readonly string DotnetFullPath = Environment.GetEnvironmentVariable("DOTNET_HOST_PATH") ?? "dotnet";
159
160 private static bool IsSelfExecutable(string proposedToolFullPath, out string toolFullPath)
161 {
162 var toolFullPathWithoutExtension = Path.Combine(Path.GetDirectoryName(proposedToolFullPath), Path.GetFileNameWithoutExtension(proposedToolFullPath));
163 var exeExtension = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : String.Empty;
164 var exeToolFullPath = $"{toolFullPathWithoutExtension}{exeExtension}";
165 if (File.Exists(exeToolFullPath))
166 {
167 toolFullPath = exeToolFullPath;
168 return true;
169 }
170
171 toolFullPath = $"{toolFullPathWithoutExtension}.dll";
172 return false;
173 }
174#endif
175 }
176}
diff --git a/src/wix/WixToolset.BuildTasks/RefreshBundleGeneratedFile.cs b/src/tools/WixToolset.HeatTasks/RefreshBundleGeneratedFile.cs
index 983695c9..8f1ad167 100644
--- a/src/wix/WixToolset.BuildTasks/RefreshBundleGeneratedFile.cs
+++ b/src/tools/WixToolset.HeatTasks/RefreshBundleGeneratedFile.cs
@@ -1,6 +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. 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 2
3namespace WixToolset.BuildTasks 3namespace WixToolset.HeatTasks
4{ 4{
5 using System; 5 using System;
6 using System.Collections; 6 using System.Collections;
@@ -8,48 +8,35 @@ namespace WixToolset.BuildTasks
8 using System.IO; 8 using System.IO;
9 using System.Xml; 9 using System.Xml;
10 using Microsoft.Build.Framework; 10 using Microsoft.Build.Framework;
11 using Microsoft.Build.Utilities;
12 11
13 /// <summary> 12 /// <summary>
14 /// This task refreshes the generated file for bundle projects. 13 /// This task refreshes the generated file for bundle projects.
15 /// </summary> 14 /// </summary>
16 public class RefreshBundleGeneratedFile : Task 15 public class RefreshBundleGeneratedFile : RefreshTask
17 { 16 {
18 /// <summary> 17 /// <summary>
19 /// The list of files to generate.
20 /// </summary>
21 [Required]
22 public ITaskItem[] GeneratedFiles { get; set; }
23
24 /// <summary>
25 /// All the project references in the project.
26 /// </summary>
27 [Required]
28 public ITaskItem[] ProjectReferencePaths { get; set; }
29
30 /// <summary>
31 /// Gets a complete list of external cabs referenced by the given installer database file. 18 /// Gets a complete list of external cabs referenced by the given installer database file.
32 /// </summary> 19 /// </summary>
33 /// <returns>True upon completion of the task execution.</returns> 20 /// <returns>True upon completion of the task execution.</returns>
34 public override bool Execute() 21 public override bool Execute()
35 { 22 {
36 ArrayList payloadGroupRefs = new ArrayList(); 23 var payloadGroupRefs = new ArrayList();
37 ArrayList packageGroupRefs = new ArrayList(); 24 var packageGroupRefs = new ArrayList();
38 for (int i = 0; i < this.ProjectReferencePaths.Length; i++) 25 for (var i = 0; i < this.ProjectReferencePaths.Length; i++)
39 { 26 {
40 ITaskItem item = this.ProjectReferencePaths[i]; 27 var item = this.ProjectReferencePaths[i];
41 28
42 if (!String.IsNullOrEmpty(item.GetMetadata(ToolsCommon.DoNotHarvest))) 29 if (!String.IsNullOrEmpty(item.GetMetadata(DoNotHarvest)))
43 { 30 {
44 continue; 31 continue;
45 } 32 }
46 33
47 string projectPath = item.GetMetadata("MSBuildSourceProjectFile"); 34 var projectPath = item.GetMetadata("MSBuildSourceProjectFile");
48 string projectName = Path.GetFileNameWithoutExtension(projectPath); 35 var projectName = Path.GetFileNameWithoutExtension(projectPath);
49 string referenceName = ToolsCommon.GetIdentifierFromName(ToolsCommon.GetMetadataOrDefault(item, "Name", projectName)); 36 var referenceName = GetIdentifierFromName(GetMetadataOrDefault(item, "Name", projectName));
50 37
51 string[] pogs = item.GetMetadata("RefProjectOutputGroups").Split(';'); 38 var pogs = item.GetMetadata("RefProjectOutputGroups").Split(';');
52 foreach (string pog in pogs) 39 foreach (var pog in pogs)
53 { 40 {
54 if (!String.IsNullOrEmpty(pog)) 41 if (!String.IsNullOrEmpty(pog))
55 { 42 {
@@ -60,43 +47,43 @@ namespace WixToolset.BuildTasks
60 } 47 }
61 } 48 }
62 49
63 XmlDocument doc = new XmlDocument(); 50 var doc = new XmlDocument();
64 51
65 XmlProcessingInstruction head = doc.CreateProcessingInstruction("xml", "version='1.0' encoding='UTF-8'"); 52 var head = doc.CreateProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
66 doc.AppendChild(head); 53 doc.AppendChild(head);
67 54
68 XmlElement rootElement = doc.CreateElement("Wix"); 55 var rootElement = doc.CreateElement("Wix");
69 rootElement.SetAttribute("xmlns", "http://wixtoolset.org/schemas/v4/wxs"); 56 rootElement.SetAttribute("xmlns", "http://wixtoolset.org/schemas/v4/wxs");
70 doc.AppendChild(rootElement); 57 doc.AppendChild(rootElement);
71 58
72 XmlElement fragment = doc.CreateElement("Fragment"); 59 var fragment = doc.CreateElement("Fragment");
73 rootElement.AppendChild(fragment); 60 rootElement.AppendChild(fragment);
74 61
75 XmlElement payloadGroup = doc.CreateElement("PayloadGroup"); 62 var payloadGroup = doc.CreateElement("PayloadGroup");
76 payloadGroup.SetAttribute("Id", "Bundle.Generated.Payloads"); 63 payloadGroup.SetAttribute("Id", "Bundle.Generated.Payloads");
77 fragment.AppendChild(payloadGroup); 64 fragment.AppendChild(payloadGroup);
78 65
79 XmlElement packageGroup = doc.CreateElement("PackageGroup"); 66 var packageGroup = doc.CreateElement("PackageGroup");
80 packageGroup.SetAttribute("Id", "Bundle.Generated.Packages"); 67 packageGroup.SetAttribute("Id", "Bundle.Generated.Packages");
81 fragment.AppendChild(packageGroup); 68 fragment.AppendChild(packageGroup);
82 69
83 foreach (string payloadGroupRef in payloadGroupRefs) 70 foreach (string payloadGroupRef in payloadGroupRefs)
84 { 71 {
85 XmlElement payloadGroupRefElement = doc.CreateElement("PayloadGroupRef"); 72 var payloadGroupRefElement = doc.CreateElement("PayloadGroupRef");
86 payloadGroupRefElement.SetAttribute("Id", payloadGroupRef); 73 payloadGroupRefElement.SetAttribute("Id", payloadGroupRef);
87 payloadGroup.AppendChild(payloadGroupRefElement); 74 payloadGroup.AppendChild(payloadGroupRefElement);
88 } 75 }
89 76
90 foreach (string packageGroupRef in packageGroupRefs) 77 foreach (string packageGroupRef in packageGroupRefs)
91 { 78 {
92 XmlElement packageGroupRefElement = doc.CreateElement("PackageGroupRef"); 79 var packageGroupRefElement = doc.CreateElement("PackageGroupRef");
93 packageGroupRefElement.SetAttribute("Id", packageGroupRef); 80 packageGroupRefElement.SetAttribute("Id", packageGroupRef);
94 packageGroup.AppendChild(packageGroupRefElement); 81 packageGroup.AppendChild(packageGroupRefElement);
95 } 82 }
96 83
97 foreach (ITaskItem item in this.GeneratedFiles) 84 foreach (var item in this.GeneratedFiles)
98 { 85 {
99 string fullPath = item.GetMetadata("FullPath"); 86 var fullPath = item.GetMetadata("FullPath");
100 87
101 payloadGroup.SetAttribute("Id", Path.GetFileNameWithoutExtension(fullPath) + ".Payloads"); 88 payloadGroup.SetAttribute("Id", Path.GetFileNameWithoutExtension(fullPath) + ".Payloads");
102 packageGroup.SetAttribute("Id", Path.GetFileNameWithoutExtension(fullPath) + ".Packages"); 89 packageGroup.SetAttribute("Id", Path.GetFileNameWithoutExtension(fullPath) + ".Packages");
diff --git a/src/wix/WixToolset.BuildTasks/RefreshGeneratedFile.cs b/src/tools/WixToolset.HeatTasks/RefreshGeneratedFile.cs
index e18ae222..1e43cc1f 100644
--- a/src/wix/WixToolset.BuildTasks/RefreshGeneratedFile.cs
+++ b/src/tools/WixToolset.HeatTasks/RefreshGeneratedFile.cs
@@ -1,6 +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. 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 2
3namespace WixToolset.BuildTasks 3namespace WixToolset.HeatTasks
4{ 4{
5 using System; 5 using System;
6 using System.Collections; 6 using System.Collections;
@@ -8,48 +8,36 @@ namespace WixToolset.BuildTasks
8 using System.IO; 8 using System.IO;
9 using System.Xml; 9 using System.Xml;
10 using Microsoft.Build.Framework; 10 using Microsoft.Build.Framework;
11 using Microsoft.Build.Utilities;
12 11
13 /// <summary> 12 /// <summary>
14 /// This task refreshes the generated file that contains ComponentGroupRefs 13 /// This task refreshes the generated file that contains ComponentGroupRefs
15 /// to harvested output. 14 /// to harvested output.
16 /// </summary> 15 /// </summary>
17 public class RefreshGeneratedFile : Task 16 public class RefreshGeneratedFile : RefreshTask
18 { 17 {
19 /// <summary> 18 /// <summary>
20 /// The list of files to generate.
21 /// </summary>
22 [Required]
23 public ITaskItem[] GeneratedFiles { get; set; }
24
25 /// <summary>
26 /// All the project references in the project.
27 /// </summary>
28 [Required]
29 public ITaskItem[] ProjectReferencePaths { get; set; }
30
31 /// <summary>
32 /// Gets a complete list of external cabs referenced by the given installer database file. 19 /// Gets a complete list of external cabs referenced by the given installer database file.
33 /// </summary> 20 /// </summary>
34 /// <returns>True upon completion of the task execution.</returns> 21 /// <returns>True upon completion of the task execution.</returns>
35 public override bool Execute() 22 public override bool Execute()
36 { 23 {
37 ArrayList componentGroupRefs = new ArrayList(); 24 var componentGroupRefs = new ArrayList();
38 for (int i = 0; i < this.ProjectReferencePaths.Length; i++) 25
26 for (var i = 0; i < this.ProjectReferencePaths.Length; i++)
39 { 27 {
40 ITaskItem item = this.ProjectReferencePaths[i]; 28 var item = this.ProjectReferencePaths[i];
41 29
42 if (!String.IsNullOrEmpty(item.GetMetadata(ToolsCommon.DoNotHarvest))) 30 if (!String.IsNullOrEmpty(item.GetMetadata(DoNotHarvest)))
43 { 31 {
44 continue; 32 continue;
45 } 33 }
46 34
47 string projectPath = item.GetMetadata("MSBuildSourceProjectFile"); 35 var projectPath = item.GetMetadata("MSBuildSourceProjectFile");
48 string projectName = Path.GetFileNameWithoutExtension(projectPath); 36 var projectName = Path.GetFileNameWithoutExtension(projectPath);
49 string referenceName = ToolsCommon.GetIdentifierFromName(ToolsCommon.GetMetadataOrDefault(item, "Name", projectName)); 37 var referenceName = GetIdentifierFromName(GetMetadataOrDefault(item, "Name", projectName));
50 38
51 string[] pogs = item.GetMetadata("RefProjectOutputGroups").Split(';'); 39 var pogs = item.GetMetadata("RefProjectOutputGroups").Split(';');
52 foreach (string pog in pogs) 40 foreach (var pog in pogs)
53 { 41 {
54 if (!String.IsNullOrEmpty(pog)) 42 if (!String.IsNullOrEmpty(pog))
55 { 43 {
@@ -58,32 +46,32 @@ namespace WixToolset.BuildTasks
58 } 46 }
59 } 47 }
60 48
61 XmlDocument doc = new XmlDocument(); 49 var doc = new XmlDocument();
62 50
63 XmlProcessingInstruction head = doc.CreateProcessingInstruction("xml", "version='1.0' encoding='UTF-8'"); 51 var head = doc.CreateProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
64 doc.AppendChild(head); 52 doc.AppendChild(head);
65 53
66 XmlElement rootElement = doc.CreateElement("Wix"); 54 var rootElement = doc.CreateElement("Wix");
67 rootElement.SetAttribute("xmlns", "http://wixtoolset.org/schemas/v4/wxs"); 55 rootElement.SetAttribute("xmlns", "http://wixtoolset.org/schemas/v4/wxs");
68 doc.AppendChild(rootElement); 56 doc.AppendChild(rootElement);
69 57
70 XmlElement fragment = doc.CreateElement("Fragment"); 58 var fragment = doc.CreateElement("Fragment");
71 rootElement.AppendChild(fragment); 59 rootElement.AppendChild(fragment);
72 60
73 XmlElement componentGroup = doc.CreateElement("ComponentGroup"); 61 var componentGroup = doc.CreateElement("ComponentGroup");
74 componentGroup.SetAttribute("Id", "Product.Generated"); 62 componentGroup.SetAttribute("Id", "Product.Generated");
75 fragment.AppendChild(componentGroup); 63 fragment.AppendChild(componentGroup);
76 64
77 foreach (string componentGroupRef in componentGroupRefs) 65 foreach (string componentGroupRef in componentGroupRefs)
78 { 66 {
79 XmlElement componentGroupRefElement = doc.CreateElement("ComponentGroupRef"); 67 var componentGroupRefElement = doc.CreateElement("ComponentGroupRef");
80 componentGroupRefElement.SetAttribute("Id", componentGroupRef); 68 componentGroupRefElement.SetAttribute("Id", componentGroupRef);
81 componentGroup.AppendChild(componentGroupRefElement); 69 componentGroup.AppendChild(componentGroupRefElement);
82 } 70 }
83 71
84 foreach (ITaskItem item in this.GeneratedFiles) 72 foreach (var item in this.GeneratedFiles)
85 { 73 {
86 string fullPath = item.GetMetadata("FullPath"); 74 var fullPath = item.GetMetadata("FullPath");
87 75
88 componentGroup.SetAttribute("Id", Path.GetFileNameWithoutExtension(fullPath)); 76 componentGroup.SetAttribute("Id", Path.GetFileNameWithoutExtension(fullPath));
89 try 77 try
diff --git a/src/tools/WixToolset.HeatTasks/RefreshTask.cs b/src/tools/WixToolset.HeatTasks/RefreshTask.cs
new file mode 100644
index 00000000..0b378272
--- /dev/null
+++ b/src/tools/WixToolset.HeatTasks/RefreshTask.cs
@@ -0,0 +1,59 @@
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
3namespace WixToolset.HeatTasks
4{
5 using System;
6 using System.Text.RegularExpressions;
7 using Microsoft.Build.Framework;
8 using Microsoft.Build.Utilities;
9
10 /// <summary>
11 /// A base MSBuild task to refresh generated files.
12 /// </summary>
13 public abstract class RefreshTask : Task
14 {
15 private static readonly Regex AddPrefix = new Regex(@"^[^a-zA-Z_]");
16 private static readonly Regex IllegalIdentifierCharacters = new Regex(@"[^A-Za-z0-9_\.]|\.{2,}"); // non 'words' and assorted valid characters
17
18 /// <summary>Metadata key name to turn off harvesting of project references.</summary>
19 protected const string DoNotHarvest = "DoNotHarvest";
20
21 /// <summary>
22 /// The list of files to generate.
23 /// </summary>
24 [Required]
25 public ITaskItem[] GeneratedFiles { get; set; }
26
27 /// <summary>
28 /// All the project references in the project.
29 /// </summary>
30 [Required]
31 public ITaskItem[] ProjectReferencePaths { get; set; }
32
33 /// <summary>
34 /// Return an identifier based on passed file/directory name
35 /// </summary>
36 /// <param name="name">File/directory name to generate identifer from</param>
37 /// <returns>A version of the name that is a legal identifier.</returns>
38 /// <remarks>This is duplicated from WiX's Common class.</remarks>
39 protected static string GetIdentifierFromName(string name)
40 {
41 var result = IllegalIdentifierCharacters.Replace(name, "_"); // replace illegal characters with "_".
42
43 // MSI identifiers must begin with an alphabetic character or an
44 // underscore. Prefix all other values with an underscore.
45 if (AddPrefix.IsMatch(name))
46 {
47 result = String.Concat("_", result);
48 }
49
50 return result;
51 }
52
53 protected static string GetMetadataOrDefault(ITaskItem item, string metadataName, string defaultValue)
54 {
55 var value = item.GetMetadata(metadataName);
56 return String.IsNullOrWhiteSpace(value) ? defaultValue : value;
57 }
58 }
59}
diff --git a/src/tools/WixToolset.HeatTasks/WixCommandLineBuilder.cs b/src/tools/WixToolset.HeatTasks/WixCommandLineBuilder.cs
new file mode 100644
index 00000000..c3989902
--- /dev/null
+++ b/src/tools/WixToolset.HeatTasks/WixCommandLineBuilder.cs
@@ -0,0 +1,56 @@
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
3namespace WixToolset.HeatTasks
4{
5 using System;
6 using System.Collections.Generic;
7 using Microsoft.Build.Utilities;
8
9 /// <summary>
10 /// Helper class for appending the command line arguments.
11 /// </summary>
12 public class WixCommandLineBuilder : CommandLineBuilder
13 {
14 /// <summary>
15 /// Append a switch to the command line if the condition is true.
16 /// </summary>
17 /// <param name="switchName">Switch to append.</param>
18 /// <param name="condition">Condition specified by the user.</param>
19 public void AppendIfTrue(string switchName, bool condition)
20 {
21 if (condition)
22 {
23 this.AppendSwitch(switchName);
24 }
25 }
26
27 /// <summary>
28 /// Append a switch to the command line if any values in the array have been specified.
29 /// </summary>
30 /// <param name="switchName">Switch to append.</param>
31 /// <param name="values">Values specified by the user.</param>
32 public void AppendArrayIfNotNull(string switchName, IEnumerable<string> values)
33 {
34 if (values != null)
35 {
36 foreach (var value in values)
37 {
38 this.AppendSwitchIfNotNull(switchName, value);
39 }
40 }
41 }
42
43 /// <summary>
44 /// Append arbitrary text to the command-line if specified.
45 /// </summary>
46 /// <param name="textToAppend">Text to append.</param>
47 public void AppendTextIfNotNull(string textToAppend)
48 {
49 if (!String.IsNullOrWhiteSpace(textToAppend))
50 {
51 this.AppendSpaceIfNotEmpty();
52 this.AppendTextUnquoted(textToAppend);
53 }
54 }
55 }
56}
diff --git a/src/tools/WixToolset.HeatTasks/WixToolset.HeatTasks.csproj b/src/tools/WixToolset.HeatTasks/WixToolset.HeatTasks.csproj
new file mode 100644
index 00000000..ea52bdfa
--- /dev/null
+++ b/src/tools/WixToolset.HeatTasks/WixToolset.HeatTasks.csproj
@@ -0,0 +1,17 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
7 <Title>WiX Toolset Heat MSBuild Tasks</Title>
8 <DebugType>embedded</DebugType>
9 <PublishRepositoryUrl>true</PublishRepositoryUrl>
10 <!-- https://github.com/Microsoft/msbuild/issues/2360 -->
11 <PlatformTarget>AnyCPU</PlatformTarget>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <PackageReference Include="Microsoft.Build.Tasks.Core" />
16 </ItemGroup>
17</Project>