Simplify reference resolution
WiX v3 extension loading had options that were rarely if ever used and library paths modeled after C++. Given the new Sdk-style model in WiX v4, we can simplify reference resolution. Fixes 6945, 6946
Rob Mensching committed
Oct 14, 2022 at 09:34 UTC
08f53f409020b12dffaa2aeefa943b667a4b9328
8 files changed
+173
-251
src/internal/WixToolset.BaseBuildTasks.Sources/FileSearchHelperMethods.cs
deleted
-57
@@ -1,57 +0,0 @@
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
-namespace WixToolset.BaseBuildTasks
4
-{
5
- using System;
6
- using System.IO;
7
-
8
- /// <summary>
9
- /// Contains helper methods on searching for files
10
- /// </summary>
11
- public static class FileSearchHelperMethods
12
- {
13
- /// <summary>
14
- /// Searches for the existence of a file in multiple directories.
15
- /// Search is satisfied if default file path is valid and exists. If not,
16
- /// file name is extracted from default path and combined with each of the directories
17
- /// looking to see if it exists. If not found, input default path is returned.
18
- /// </summary>
19
- /// <param name="directories">Array of directories to look in, without filenames in them</param>
20
- /// <param name="defaultFullPath">Default path - to use if not found</param>
21
- /// <returns>File path if file found. Empty string if not found</returns>
22
- public static string SearchFilePaths(string[] directories, string defaultFullPath)
23
- {
24
- if (String.IsNullOrEmpty(defaultFullPath))
25
- {
26
- return String.Empty;
27
- }
28
-
29
- if (File.Exists(defaultFullPath))
30
- {
31
- return defaultFullPath;
32
- }
33
-
34
- if (directories == null)
35
- {
36
- return String.Empty;
37
- }
38
-
39
- var fileName = Path.GetFileName(defaultFullPath);
40
- foreach (var currentPath in directories)
41
- {
42
- if (String.IsNullOrWhiteSpace(currentPath))
43
- {
44
- continue;
45
- }
46
-
47
- var path = Path.Combine(currentPath, fileName);
48
- if (File.Exists(path))
49
- {
50
- return path;
51
- }
52
- }
53
-
54
- return String.Empty;
55
- }
56
- }
57
-}
src/internal/WixToolset.BaseBuildTasks.Sources/WixCommandLineBuilder.cs
-73
@@ -75,79 +75,6 @@ namespace WixToolset.BaseBuildTasks
75
}
76
}
77
78
- /// <summary>
79
- /// Build the extensions argument. Each extension is searched in the current folder, user defined search
80
- /// directories (ReferencePath), HintPath, and under Wix Extension Directory in that order.
81
- /// The order of precedence is based off of that described in Microsoft.Common.Targets's SearchPaths
82
- /// property for the ResolveAssemblyReferences task.
83
- /// </summary>
84
- /// <param name="extensions">The list of extensions to include.</param>
85
- /// <param name="wixExtensionDirectory">Evaluated default folder for Wix Extensions</param>
86
- /// <param name="referencePaths">User defined reference directories to search in</param>
87
- public void AppendExtensions(ITaskItem[] extensions, string wixExtensionDirectory, string [] referencePaths)
88
- {
89
- if (extensions == null)
90
- {
91
- return;
92
- }
93
-
94
- foreach (ITaskItem extension in extensions)
95
- {
96
- string className = extension.GetMetadata("Class");
97
-
98
- string fileName = Path.GetFileName(extension.ItemSpec);
99
-
100
- if (String.IsNullOrEmpty(Path.GetExtension(fileName)))
101
- {
102
- fileName += ".dll";
103
- }
104
-
105
- // First try reference paths
106
- var resolvedPath = FileSearchHelperMethods.SearchFilePaths(referencePaths, fileName);
107
-
108
- if (String.IsNullOrEmpty(resolvedPath))
109
- {
110
- // Now try HintPath
111
- resolvedPath = extension.GetMetadata("HintPath");
112
-
113
- if (!File.Exists(resolvedPath))
114
- {
115
- // Now try the item itself
116
- resolvedPath = extension.ItemSpec;
117
-
118
- if (String.IsNullOrEmpty(Path.GetExtension(resolvedPath)))
119
- {
120
- resolvedPath += ".dll";
121
- }
122
-
123
- if (!File.Exists(resolvedPath))
124
- {
125
- if (!String.IsNullOrEmpty(wixExtensionDirectory))
126
- {
127
- // Now try the extension directory
128
- resolvedPath = Path.Combine(wixExtensionDirectory, Path.GetFileName(resolvedPath));
129
- }
130
-
131
- if (!File.Exists(resolvedPath))
132
- {
133
- // Extension wasn't found, just set it to the extension name passed in
134
- resolvedPath = extension.ItemSpec;
135
- }
136
- }
137
- }
138
- }
139
-
140
- if (String.IsNullOrEmpty(className))
141
- {
142
- this.AppendSwitchIfNotNull("-ext ", resolvedPath);
143
- }
144
- else
145
- {
146
- this.AppendSwitchIfNotNull("-ext ", className + ", " + resolvedPath);
147
- }
148
- }
149
- }
150
-
78
/// <summary>
79
/// Append arbitrary text to the command-line if specified.
80
/// </summary>
src/wix/WixToolset.BuildTasks/ResolveWixReferences.cs
+77
-70
@@ -4,9 +4,10 @@ namespace WixToolset.BuildTasks
4
{
5
using System;
6
using System.Collections.Generic;
7
- using Microsoft.Build.Utilities;
8
- using Microsoft.Build.Framework;
7
using System.IO;
8
+ using System.Linq;
9
+ using Microsoft.Build.Framework;
10
+ using Microsoft.Build.Utilities;
11
12
/// <summary>
13
/// This task searches for paths to references using the order specified in SearchPaths.
@@ -15,14 +16,14 @@ namespace WixToolset.BuildTasks
16
{
17
/// <summary>
18
/// Token value used in SearchPaths to indicate that the item's HintPath metadata should
18
- /// be searched as a full file path to resolve the reference.
19
+ /// be searched as a full file path to resolve the reference.
20
/// Must match wix.targets, case sensitive.
21
/// </summary>
22
private const string HintPathToken = "{HintPathFromItem}";
23
24
/// <summary>
25
/// Token value used in SearchPaths to indicate that the item's Identity should
25
- /// be searched as a full file path to resolve the reference.
26
+ /// be searched as a full file path to resolve the reference.
27
/// Must match wix.targets, case sensitive.
28
/// </summary>
29
private const string RawFileNameToken = "{RawFileName}";
@@ -34,24 +35,18 @@ namespace WixToolset.BuildTasks
35
public ITaskItem[] WixReferences { get; set; }
36
37
/// <summary>
37
- /// The directories or special locations that are searched to find the files
38
- /// on disk that represent the references. The order in which the search paths are listed
39
- /// is important. For each reference, the list of paths is searched from left to right.
40
- /// When a file that represents the reference is found, that search stops and the search
41
- /// for the next reference starts.
42
- ///
43
- /// This parameter accepts the following types of values:
44
- /// A directory path.
45
- /// {HintPathFromItem}: Specifies that the task will examine the HintPath metadata
46
- /// of the base item.
47
- /// TODO : {CandidateAssemblyFiles}: Specifies that the task will examine the files
48
- /// passed in through the CandidateAssemblyFiles parameter.
49
- /// TODO : {Registry:_AssemblyFoldersBase_, _RuntimeVersion_, _AssemblyFoldersSuffix_}:
50
- /// TODO : {AssemblyFolders}: Specifies the task will use the Visual Studio.NET 2003
51
- /// finding-assemblies-from-registry scheme.
52
- /// TODO : {GAC}: Specifies the task will search in the GAC.
53
- /// {RawFileName}: Specifies the task will consider the Include value of the item to be
54
- /// an exact path and file name.
38
+ /// The directories or special locations that are searched to find the files
39
+ /// on disk that represent the references. The order in which the search paths are listed
40
+ /// is important. For each reference, the list of paths is searched from left to right.
41
+ /// When a file that represents the reference is found, that search stops and the search
42
+ /// for the next reference starts.
43
+ ///
44
+ /// This parameter accepts the following types of values:
45
+ /// A directory path.
46
+ /// {HintPathFromItem}: Specifies that the task will examine the HintPath metadata
47
+ /// of the base item.
48
+ /// {RawFileName}: Specifies the task will consider the Include value of the item to be
49
+ /// an exact path and file name.
50
/// </summary>
51
public string[] SearchPaths { get; set; }
52
@@ -66,6 +61,12 @@ namespace WixToolset.BuildTasks
61
[Output]
62
public ITaskItem[] ResolvedWixReferences { get; private set; }
63
64
+ /// <summary>
65
+ /// Output items that contain the same metadata as input references and cannot be found.
66
+ /// </summary>
67
+ [Output]
68
+ public ITaskItem[] UnresolvedWixReferences { get; private set; }
69
+
70
/// <summary>
71
/// Resolves reference paths by searching for referenced items using the specified SearchPaths.
72
/// </summary>
@@ -73,16 +74,25 @@ namespace WixToolset.BuildTasks
74
public override bool Execute()
75
{
76
var resolvedReferences = new List<ITaskItem>();
77
+ var unresolvedReferences = new List<ITaskItem>();
78
var uniqueReferences = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
79
78
- foreach (var reference in this.WixReferences)
80
+ foreach (var reference in this.WixReferences.Where(r => !String.IsNullOrWhiteSpace(r.ItemSpec)))
81
{
80
- var resolvedReference = ResolveWixReferences.ResolveReference(reference, this.SearchPaths, this.SearchFilenameExtensions, this.Log);
82
+ (var resolvedReference, var found) = this.ResolveReference(reference, this.SearchPaths, this.SearchFilenameExtensions);
83
84
if (uniqueReferences.Add(resolvedReference.ItemSpec))
85
{
84
- this.Log.LogMessage(MessageImportance.Low, "Resolved path {0}", resolvedReference.ItemSpec);
85
- resolvedReferences.Add(resolvedReference);
86
+ if (found)
87
+ {
88
+ this.Log.LogMessage(MessageImportance.Low, "Resolved path {0}", resolvedReference.ItemSpec);
89
+ resolvedReferences.Add(resolvedReference);
90
+ }
91
+ else
92
+ {
93
+ this.Log.LogWarning(null, "WXE0001", null, null, 0, 0, 0, 0, "Unable to find extension {0}.", resolvedReference.ItemSpec);
94
+ unresolvedReferences.Add(resolvedReference);
95
+ }
96
}
97
else
98
{
@@ -91,6 +101,7 @@ namespace WixToolset.BuildTasks
101
}
102
103
this.ResolvedWixReferences = resolvedReferences.ToArray();
104
+ this.UnresolvedWixReferences = unresolvedReferences.ToArray();
105
return true;
106
}
107
@@ -101,80 +112,76 @@ namespace WixToolset.BuildTasks
112
/// <param name="reference">The referenced item.</param>
113
/// <param name="searchPaths">The paths to search.</param>
114
/// <param name="searchFilenameExtensions">Filename extensions to check.</param>
104
- /// <param name="log">Logging helper.</param>
115
/// <returns>The resolved reference item, or the original reference if it could not be resolved.</returns>
106
- public static ITaskItem ResolveReference(ITaskItem reference, string[] searchPaths, string[] searchFilenameExtensions, TaskLoggingHelper log)
116
+ public (ITaskItem, bool) ResolveReference(ITaskItem reference, string[] searchPaths, string[] searchFilenameExtensions)
117
{
108
- if (reference == null)
109
- {
110
- throw new ArgumentNullException("reference");
111
- }
118
+ // Ensure we first check the reference without adding additional search filename extensions.
119
+ searchFilenameExtensions = searchFilenameExtensions == null ? new[] { String.Empty } : searchFilenameExtensions.Prepend(String.Empty).ToArray();
120
+
121
+ // Copy all the metadata from the source
122
+ var resolvedReference = new TaskItem(reference);
123
+ this.Log.LogMessage(MessageImportance.Low, "WixReference: {0}", reference.ItemSpec);
124
+
125
+ var found = false;
126
127
+ // Nothing to search, so just resolve the original reference item.
128
if (searchPaths == null)
129
{
115
- // Nothing to search, so just return the original reference item.
116
- return reference;
117
- }
130
+ if (this.ResolveFilenameExtensions(resolvedReference, resolvedReference.ItemSpec, searchFilenameExtensions))
131
+ {
132
+ found = true;
133
+ }
134
119
- if (searchFilenameExtensions == null)
120
- {
121
- searchFilenameExtensions = new string[] { };
135
+ return (resolvedReference, found);
136
}
137
124
- // Copy all the metadata from the source
125
- var resolvedReference = new TaskItem(reference);
126
- log.LogMessage(MessageImportance.Low, "WixReference: {0}", reference.ItemSpec);
127
-
128
- // Now find the resolved path based on our order of precedence
138
+ // Otherwise, now try to find the resolved path based on the order of precedence from search paths.
139
foreach (var searchPath in searchPaths)
140
{
131
- log.LogMessage(MessageImportance.Low, "Trying {0}", searchPath);
132
- if (searchPath.Equals(HintPathToken, StringComparison.Ordinal))
141
+ this.Log.LogMessage(MessageImportance.Low, "Trying {0}", searchPath);
142
+ if (HintPathToken.Equals(searchPath, StringComparison.Ordinal))
143
{
144
var path = reference.GetMetadata("HintPath");
135
- log.LogMessage(MessageImportance.Low, "Trying path {0}", path);
145
+ if (String.IsNullOrWhiteSpace(path))
146
+ {
147
+ continue;
148
+ }
149
+
150
+ this.Log.LogMessage(MessageImportance.Low, "Trying path {0}", path);
151
if (File.Exists(path))
152
{
153
resolvedReference.ItemSpec = path;
154
+ found = true;
155
break;
156
}
157
}
142
- else if (searchPath.Equals(RawFileNameToken, StringComparison.Ordinal))
158
+ else if (RawFileNameToken.Equals(searchPath, StringComparison.Ordinal))
159
{
144
- log.LogMessage(MessageImportance.Low, "Trying path {0}", resolvedReference.ItemSpec);
145
- if (File.Exists(resolvedReference.ItemSpec))
146
- {
147
- break;
148
- }
149
-
150
- if (ResolveWixReferences.ResolveFilenameExtensions(resolvedReference,
151
- resolvedReference.ItemSpec, searchFilenameExtensions, log))
160
+ if (this.ResolveFilenameExtensions(resolvedReference, resolvedReference.ItemSpec, searchFilenameExtensions))
161
{
162
+ found = true;
163
break;
164
}
165
}
166
else
167
{
158
- var path = Path.Combine(searchPath, Path.GetFileName(reference.ItemSpec));
159
- log.LogMessage(MessageImportance.Low, "Trying path {0}", path);
160
- if (File.Exists(path))
161
- {
162
- resolvedReference.ItemSpec = path;
163
- break;
164
- }
168
+ var path = Path.Combine(searchPath, reference.ItemSpec);
169
166
- if (ResolveWixReferences.ResolveFilenameExtensions(resolvedReference,
167
- path, searchFilenameExtensions, log))
170
+ if (this.ResolveFilenameExtensions(resolvedReference, path, searchFilenameExtensions))
171
{
172
+ found = true;
173
break;
174
}
175
}
176
}
177
174
- // Normalize the item path
175
- resolvedReference.ItemSpec = resolvedReference.GetMetadata("FullPath");
178
+ if (found)
179
+ {
180
+ // Normalize the item spec to the full path.
181
+ resolvedReference.ItemSpec = resolvedReference.GetMetadata("FullPath");
182
+ }
183
177
- return resolvedReference;
184
+ return (resolvedReference, found);
185
}
186
187
/// <summary>
@@ -183,14 +190,14 @@ namespace WixToolset.BuildTasks
190
/// <param name="reference">The reference being resolved.</param>
191
/// <param name="basePath">Full filename path without extension.</param>
192
/// <param name="filenameExtensions">Filename extensions to check.</param>
186
- /// <param name="log">Logging helper.</param>
193
/// <returns>True if the item was resolved, else false.</returns>
188
- private static bool ResolveFilenameExtensions(ITaskItem reference, string basePath, string[] filenameExtensions, TaskLoggingHelper log)
194
+ private bool ResolveFilenameExtensions(ITaskItem reference, string basePath, string[] filenameExtensions)
195
{
196
foreach (var filenameExtension in filenameExtensions)
197
{
198
var path = basePath + filenameExtension;
193
- log.LogMessage(MessageImportance.Low, "Trying path {0}", path);
199
+ this.Log.LogMessage(MessageImportance.Low, "Trying path {0}", path);
200
+
201
if (File.Exists(path))
202
{
203
reference.ItemSpec = path;
src/wix/WixToolset.BuildTasks/WixBuild.cs
+1
-5
@@ -18,8 +18,6 @@ namespace WixToolset.BuildTasks
18
19
public ITaskItem[] Extensions { get; set; }
20
21
- public string ExtensionDirectory { get; set; }
22
-
21
public string[] IncludeSearchPaths { get; set; }
22
23
public string InstallerPlatform { get; set; }
@@ -45,8 +43,6 @@ namespace WixToolset.BuildTasks
43
[Required]
44
public ITaskItem[] SourceFiles { get; set; }
45
48
- public string[] ReferencePaths { get; set; }
49
-
46
public ITaskItem[] BindInputPaths { get; set; }
47
48
public bool BindFiles { get; set; }
@@ -75,7 +71,7 @@ namespace WixToolset.BuildTasks
71
commandLineBuilder.AppendArrayIfNotNull("-culture ", this.Cultures);
72
commandLineBuilder.AppendArrayIfNotNull("-d ", this.DefineConstants);
73
commandLineBuilder.AppendArrayIfNotNull("-I ", this.IncludeSearchPaths);
78
- commandLineBuilder.AppendExtensions(this.Extensions, this.ExtensionDirectory, this.ReferencePaths);
74
+ commandLineBuilder.AppendArrayIfNotNull("-ext ", this.Extensions);
75
commandLineBuilder.AppendSwitchIfNotNull("-cc ", this.CabinetCachePath);
76
commandLineBuilder.AppendSwitchIfNotNull("-intermediatefolder ", this.IntermediateDirectory);
77
commandLineBuilder.AppendSwitchIfNotNull("-trackingfile ", this.BindTrackingFile);
src/wix/WixToolset.Sdk/tools/wix.targets
+12
-29
@@ -128,10 +128,6 @@
128
<TargetPdbPath Condition=" '$(TargetPdbPath)' == '' ">$(TargetPdbDir)$(TargetPdbFileName)</TargetPdbPath>
129
</PropertyGroup>
130
131
- <PropertyGroup>
132
- <WixExtDir Condition=" '$(WixExtDir)' == ''">$(WixBinDir)</WixExtDir>
133
- </PropertyGroup>
134
-
131
<PropertyGroup>
132
<BindTrackingFilePrefix Condition=" '$(BindTrackingFilePrefix)' == '' ">$(MSBuildProjectFile).BindTracking</BindTrackingFilePrefix>
133
<BindTrackingFileExtension Condition=" '$(BindTrackingFileExtension)' == '' ">.txt</BindTrackingFileExtension>
@@ -362,10 +358,9 @@
358
359
By default the WixLibrarySearchPaths property is set to find libraries in the following order:
360
365
- (1) $(ReferencePaths) - the reference paths property, which comes from the .USER file.
361
+ (1) $(ReferencePaths) - the reference paths property.
362
(2) The hintpath from the referenced item itself, indicated by {HintPathFromItem}.
363
(3) Treat the reference's Include as if it were a real file name.
368
- (4) Path specified by the WixExtDir property.
364
365
[IN]
366
@(WixLibrary) - the list of .wixlib files.
@@ -381,39 +376,33 @@
376
</PropertyGroup>
377
<Target
378
Name="ResolveWixLibraryReferences"
384
- DependsOnTargets="$(ResolveWixLibraryReferencesDependsOn)">
379
+ DependsOnTargets="$(ResolveWixLibraryReferencesDependsOn)"
380
+ Condition=" '@(WixLibrary)' != ''">
381
382
<PropertyGroup>
387
- <WixLibrarySearchPaths Condition=" '$(WixLibrarySearchPaths)' == '' ">$(ReferencePaths);{HintPathFromItem};{RawFileName};$(WixExtDir)</WixLibrarySearchPaths>
383
+ <WixLibrarySearchPaths Condition=" '$(WixLibrarySearchPaths)' == '' ">$(ReferencePaths);{HintPathFromItem};{RawFileName}</WixLibrarySearchPaths>
384
</PropertyGroup>
385
386
<ResolveWixReferences
387
WixReferences="@(WixLibrary)"
388
SearchPaths="$(WixLibrarySearchPaths)"
393
- SearchFilenameExtensions=".wixlib"
394
- Condition=" '@(WixLibrary)' != ''">
395
- <Output TaskParameter="ResolvedWixReferences" ItemName="_AllResolvedWixLibraryPaths" />
389
+ SearchFilenameExtensions=".wixlib">
390
+ <Output TaskParameter="ResolvedWixReferences" ItemName="_ResolvedWixLibraryPaths" />
391
+ <Output TaskParameter="UnresolvedWixReferences" ItemName="_UnresolvedWixLibraryPaths" />
392
</ResolveWixReferences>
397
-
398
- <RemoveDuplicates Inputs="@(_AllResolvedWixLibraryPaths)">
399
- <Output TaskParameter="Filtered" ItemName="_ResolvedWixLibraryPaths" />
400
- </RemoveDuplicates>
393
</Target>
394
395
<!--
396
================================================================================================
397
ResolveWixExtensionReferences
398
407
- Resolves WiX extension references to full paths. Any properties you use
408
- to resolve paths to extensions must be defined before importing this
409
- file or the extensions will be automatically resolved to $(WixExtDir).
399
+ Resolves WiX extension references to full paths.
400
401
By default the WixExtensionSearchPaths property is set to find extensions in the following order:
402
413
- (1) $(ReferencePaths) - the reference paths property, which comes from the .USER file.
403
+ (1) $(ReferencePaths) - the reference paths property.
404
(2) The hintpath from the referenced item itself, indicated by {HintPathFromItem}.
405
(3) Treat the reference's Include as if it were a real file name.
416
- (4) Path specified by the WixExtDir property.
406
407
[IN]
408
@(WixExtension) - WixExtension item group
@@ -431,20 +420,16 @@
420
Condition=" '@(WixExtension)' != ''">
421
422
<PropertyGroup>
434
- <WixExtensionSearchPaths Condition=" '$(WixExtensionSearchPaths)' == '' ">$(ReferencePaths);{HintPathFromItem};{RawFileName};$(WixExtDir)</WixExtensionSearchPaths>
423
+ <WixExtensionSearchPaths Condition=" '$(WixExtensionSearchPaths)' == '' ">$(ReferencePaths);{HintPathFromItem};{RawFileName}</WixExtensionSearchPaths>
424
</PropertyGroup>
425
426
<ResolveWixReferences
427
WixReferences="@(WixExtension)"
428
SearchPaths="$(WixExtensionSearchPaths)"
429
SearchFilenameExtensions=".wixext.dll">
441
- <Output TaskParameter="ResolvedWixReferences" ItemName="_AllResolvedWixExtensionPaths" />
430
+ <Output TaskParameter="ResolvedWixReferences" ItemName="_ResolvedWixExtensionPaths" />
431
+ <Output TaskParameter="UnresolvedWixReferences" ItemName="_UnresolvedWixExtensionPaths" />
432
</ResolveWixReferences>
443
-
444
- <!-- Remove duplicate extension items that would cause build errors -->
445
- <RemoveDuplicates Inputs="@(_AllResolvedWixExtensionPaths)">
446
- <Output TaskParameter="Filtered" ItemName="_ResolvedWixExtensionPaths" />
447
- </RemoveDuplicates>
433
</Target>
434
435
<!--
@@ -599,7 +584,6 @@
584
585
Cultures="%(CultureGroup.Identity)"
586
602
- ExtensionDirectory="$(WixExtDir)"
587
Extensions="@(_ResolvedWixExtensionPaths)"
588
589
IntermediateDirectory="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)"
@@ -615,7 +599,6 @@
599
InstallerPlatform="$(InstallerPlatform)"
600
NoLogo="true"
601
Pedantic="$(Pedantic)"
618
- ReferencePaths="$(ReferencePaths)"
602
603
BindInputPaths="@(LinkerBindInputPaths)"
604
BindFiles="$(BindFiles)"
src/wix/test/WixToolsetTest.Sdk/MsbuildFixture.cs
+58
-17
@@ -29,7 +29,7 @@ namespace WixToolsetTest.Sdk
29
var binFolder = Path.Combine(baseFolder, @"bin\");
30
var projectPath = Path.Combine(baseFolder, "SimpleBundle.wixproj");
31
32
- var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] {
32
+ var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] {
33
MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
34
"-p:SignOutput=true",
35
});
@@ -162,7 +162,7 @@ namespace WixToolsetTest.Sdk
162
var platformSwitches = result.Output.Where(line => line.Contains("-platform x86"));
163
Assert.Single(platformSwitches);
164
165
- var warnings = result.Output.Where(line => line.Contains(": warning")).Select(ExtractWarningFromMessage).ToArray();
165
+ var warnings = result.Output.Where(line => line.Contains(": warning")).Select(line => ExtractWarningFromMessage(line, baseFolder)).ToArray();
166
WixAssert.CompareLineByLine(new[]
167
{
168
@"WIX1118: The variable 'Variable' with value 'DifferentValue' was previously declared with value 'Value'.",
@@ -173,7 +173,7 @@ namespace WixToolsetTest.Sdk
173
@"WIX1122: The installer database '<basefolder>\obj\x86\Release\en-US\MsiPackage.msi' has external cabs, but at least one of them is not signed. Please ensure that all external cabs are signed, if you mean to sign them. If you don't mean to sign them, there is no need to inscribe the MSI as part of your build."
174
}, warnings);
175
176
- var testMessages = result.Output.Where(line => line.Contains("TEST:")).Select(ReplacePathsInMessage).ToArray();
176
+ var testMessages = result.Output.Where(line => line.Contains("TEST:")).Select(line => ReplacePathsInMessage(line, baseFolder)).ToArray();
177
WixAssert.CompareLineByLine(new[]
178
{
179
@"TEST: SignCabs: <basefolder>\obj\x86\Release\en-US\cab1.cab",
@@ -191,20 +191,6 @@ namespace WixToolsetTest.Sdk
191
@"bin\x86\Release\en-US\MsiPackage.wixpdb",
192
}, paths);
193
}
194
-
195
- string ExtractWarningFromMessage(string message)
196
- {
197
- const string prefix = ": warning ";
198
-
199
- var start = message.IndexOf(prefix) + prefix.Length;
200
- var end = message.LastIndexOf("[");
201
- return ReplacePathsInMessage(message.Substring(start, end - start));
202
- }
203
-
204
- string ReplacePathsInMessage(string message)
205
- {
206
- return message.Replace(baseFolder, "<basefolder>").Trim();
207
- }
194
}
195
196
[Theory]
@@ -585,6 +571,46 @@ namespace WixToolsetTest.Sdk
571
}
572
}
573
574
+
575
+ [Theory]
576
+ [InlineData(BuildSystem.DotNetCoreSdk)]
577
+ [InlineData(BuildSystem.MSBuild)]
578
+ [InlineData(BuildSystem.MSBuild64)]
579
+ public void CanBuildWithWarningWhenExtensionIsMissing(BuildSystem buildSystem)
580
+ {
581
+ var sourceFolder = TestData.Get(@"TestData", "WixlibMissingExtension");
582
+
583
+ using (var fs = new TestDataFolderFileSystem())
584
+ {
585
+ fs.Initialize(sourceFolder);
586
+ var baseFolder = fs.BaseFolder;
587
+ var binFolder = Path.Combine(baseFolder, @"bin\");
588
+ var projectPath = Path.Combine(baseFolder, "WixlibMissingExtension.wixproj");
589
+
590
+ var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] {
591
+ MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
592
+ "-p:SignOutput=true",
593
+ });
594
+ result.AssertSuccess();
595
+
596
+ var warnings = result.Output.Where(line => line.Contains(": warning")).Select(line => ExtractWarningFromMessage(line, baseFolder)).ToArray();
597
+ WixAssert.CompareLineByLine(new[]
598
+ {
599
+ "WXE0001: Unable to find extension DoesNotExist.wixext.dll.",
600
+ "WXE0001: Unable to find extension DoesNotExist.wixext.dll.",
601
+ }, warnings);
602
+
603
+ var paths = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
604
+ .Select(s => s.Substring(baseFolder.Length + 1))
605
+ .OrderBy(s => s)
606
+ .ToArray();
607
+ WixAssert.CompareLineByLine(new[]
608
+ {
609
+ @"bin\Release\WixlibMissingExtension.wixlib",
610
+ }, paths);
611
+ }
612
+ }
613
+
614
[Theory(Skip = "Depends on creating broken publish which is not supported at this time")]
615
[InlineData(BuildSystem.DotNetCoreSdk)]
616
[InlineData(BuildSystem.MSBuild)]
@@ -610,5 +636,20 @@ namespace WixToolsetTest.Sdk
636
Assert.Contains(result.Output, m => m.Contains(expectedMessage));
637
}
638
}
639
+
640
+ private static string ExtractWarningFromMessage(string message, string baseFolder)
641
+ {
642
+ const string prefix = ": warning ";
643
+
644
+ var start = message.IndexOf(prefix) + prefix.Length;
645
+ var end = message.LastIndexOf("[");
646
+
647
+ return ReplacePathsInMessage(message.Substring(start, end - start), baseFolder);
648
+ }
649
+
650
+ private static string ReplacePathsInMessage(string message, string baseFolder)
651
+ {
652
+ return message.Replace(baseFolder, "<basefolder>").Trim();
653
+ }
654
}
655
}
src/wix/test/WixToolsetTest.Sdk/TestData/WixlibMissingExtension/Library.wxs
new
+7
@@ -0,0 +1,7 @@
1
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2
+ <Fragment>
3
+ <StandardDirectory Id="ProgramFilesFolder">
4
+ <Directory Id="WixLibFolder" />
5
+ </StandardDirectory>
6
+ </Fragment>
7
+</Wix>
src/wix/test/WixToolsetTest.Sdk/TestData/WixlibMissingExtension/WixlibMissingExtension.wixproj
new
+18
@@ -0,0 +1,18 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Project>
3
+ <Import Project="$(WixMSBuildProps)" />
4
+
5
+ <PropertyGroup>
6
+ <OutputType>Library</OutputType>
7
+ </PropertyGroup>
8
+
9
+ <ItemGroup>
10
+ <Compile Include="Library.wxs" />
11
+ </ItemGroup>
12
+
13
+ <ItemGroup>
14
+ <WixExtension Include="DoesNotExist.wixext.dll" />
15
+ </ItemGroup>
16
+
17
+ <Import Project="$(WixTargetsPath)" />
18
+</Project>