|
1 | 1 | // Licensed to the .NET Foundation under one or more agreements.
|
2 | 2 | // The .NET Foundation licenses this file to you under the MIT license.
|
3 | 3 |
|
| 4 | +using Microsoft.Build.Framework; |
| 5 | +using Microsoft.Build.Utilities; |
4 | 6 | using System;
|
5 | 7 | using System.Collections.Generic;
|
6 | 8 | using System.IO;
|
7 | 9 | using System.IO.Compression;
|
8 | 10 | using System.Linq;
|
9 | 11 | using System.Text;
|
| 12 | +using System.Text.RegularExpressions; |
10 | 13 | using System.Xml.Linq;
|
11 |
| -using Microsoft.Build.Framework; |
12 |
| -using Microsoft.Build.Utilities; |
13 | 14 |
|
B2EA
14 | 15 | namespace Microsoft.DotNet.Build.Tasks.Installers
|
15 | 16 | {
|
@@ -58,6 +59,7 @@ public class CreateWixBuildWixpack : Task
|
58 | 59 | public string WixpackWorkingDir { get; set; }
|
59 | 60 |
|
60 | 61 | private Dictionary<string, string> _defineConstantsDictionary;
|
| 62 | + private Dictionary<string, string> _defineVariablesDictionary; |
61 | 63 | private string _wixprojDir;
|
62 | 64 | private string _installerFilename;
|
63 | 65 |
|
@@ -99,9 +101,10 @@ public override bool Execute()
|
99 | 101 | throw new InvalidOperationException("ProjectPath not defined in DefineConstants. Task cannot proceed.");
|
100 | 102 | }
|
101 | 103 |
|
| 104 | + CopyIncludeSearchPathsContents(); |
| 105 | + ProcessIncludeFiles(); |
102 | 106 | CopySourceFilesAndContent();
|
103 | 107 | CopyExtensions();
|
104 |
| - CopyIncludeSearchPathsContents(); |
105 | 108 | UpdatePaths();
|
106 | 109 | GenerateWixBuildCommandLineFile();
|
107 | 110 | CreateWixpackPackage();
|
@@ -155,6 +158,42 @@ private void CopyIncludeSearchPathsContents()
|
155 | 158 | }
|
156 | 159 | }
|
157 | 160 |
|
| 161 | + private void ProcessIncludeFiles() |
| 162 | + { |
| 163 | + _defineVariablesDictionary = new Dictionary<string, string>(System.StringComparer.OrdinalIgnoreCase); |
| 164 | + foreach (var includeFile in Directory.GetFiles(WixpackWorkingDir, "*.wxi", SearchOption.AllDirectories)) |
| 165 | + { |
| 166 | + try |
| 167 | + { |
| 168 | + // We're processing a Wix include file, which contains preprocessor elements |
| 169 | + // in the format <?define KEY="value"?> |
| 170 | + // It can also contain XML comments that we need to remove, so we don't ingest |
| 171 | + // variables from elements that are commented out. |
| 172 | + |
| 173 | + XDocument xmlDocument = XDocument.Load(includeFile); |
| 174 | + xmlDocument.DescendantNodes() |
| 175 | + .OfType<XComment>() |
| 176 | + .ToList() |
| 177 | + .ForEach(comment => comment.Remove()); |
| 178 | + |
| 179 | + // We use regular expressions to process wix preprocessor defines |
| 180 | + var regex = new Regex(@"<\?define\s+(\w+)\s*=\s*""([^""]*)""\s*\?>"); |
| 181 | + |
| 182 | + foreach (Match match in regex.Matches(xmlDocument.ToString())) |
| 183 | + { |
| 184 | + if (match.Groups.Count == 3) |
| 185 | + { |
| 186 | + _defineVariablesDictionary[match.Groups[1].Value] = match.Groups[2].Value; |
| 187 | + } |
| 188 | + } |
| 189 | + } |
| 190 | + catch (Exception ex) |
| 191 | + { |
| 192 | + Log.LogError($"Error processing include file {includeFile}: {ex.Message}"); |
| 193 | + } |
| 194 | + } |
| 195 | + } |
| 196 | + |
158 | 197 | private void UpdatePaths()
|
159 | 198 | {
|
160 | 199 | // Update ProjectDir to just '.'
|
@@ -475,8 +514,10 @@ private string ResolvePath(string path)
|
475 | 514 | }
|
476 | 515 |
|
477 | 516 | var varName = path.Substring(startIdx + 2, endIdx - (startIdx + 2));
|
478 |
| - if (_defineConstantsDictionary.TryGetValue(varName, out var varValue)) |
| 517 | + if (_defineConstantsDictionary.TryGetValue(varName, out var varValue) || |
| 518 | + _defineVariablesDictionary.TryGetValue(varName, out varValue)) |
479 | 519 | {
|
| 520 | + |
480 | 521 | path = path.Substring(0, startIdx) + varValue + path.Substring(endIdx + 1);
|
481 | 522 | }
|
482 | 523 | else
|
|
0 commit comments