diff options
author | Rob Mensching <rob@firegiant.com> | 2021-01-05 15:13:37 -0800 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2021-01-05 23:18:34 -0800 |
commit | 0d1851c79901ba6ddbba9bb63f758760fe5be994 (patch) | |
tree | 2ccb45459fe4290e9c3fb4ad698c20f9cd55203d | |
parent | b00c72ed0ef19d2e46f60361fa06821b0bd5ec94 (diff) | |
download | wix-0d1851c79901ba6ddbba9bb63f758760fe5be994.tar.gz wix-0d1851c79901ba6ddbba9bb63f758760fe5be994.tar.bz2 wix-0d1851c79901ba6ddbba9bb63f758760fe5be994.zip |
Fix handling of duplicate directories
7 files changed, 92 insertions, 15 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/AddRequiredStandardDirectories.cs b/src/WixToolset.Core.WindowsInstaller/Bind/AddRequiredStandardDirectories.cs index 4597639b..ee3bcc91 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/AddRequiredStandardDirectories.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/AddRequiredStandardDirectories.cs | |||
@@ -27,7 +27,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
27 | public void Execute() | 27 | public void Execute() |
28 | { | 28 | { |
29 | var directories = this.Section.Symbols.OfType<DirectorySymbol>().ToList(); | 29 | var directories = this.Section.Symbols.OfType<DirectorySymbol>().ToList(); |
30 | var directoriesById = directories.ToDictionary(d => d.Id.Id); | 30 | var directoryIds = new SortedSet<string>(directories.Select(d => d.Id.Id)); |
31 | 31 | ||
32 | foreach (var directory in directories) | 32 | foreach (var directory in directories) |
33 | { | 33 | { |
@@ -42,20 +42,20 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
42 | } | 42 | } |
43 | else | 43 | else |
44 | { | 44 | { |
45 | this.EnsureStandardDirectoryAdded(directoriesById, parentDirectoryId, directory.SourceLineNumbers); | 45 | this.EnsureStandardDirectoryAdded(directoryIds, parentDirectoryId, directory.SourceLineNumbers); |
46 | } | 46 | } |
47 | } | 47 | } |
48 | 48 | ||
49 | if (!directoriesById.ContainsKey("TARGETDIR") && WindowsInstallerStandard.TryGetStandardDirectory("TARGETDIR", out var targetDir)) | 49 | if (!directoryIds.Contains("TARGETDIR") && WindowsInstallerStandard.TryGetStandardDirectory("TARGETDIR", out var targetDir)) |
50 | { | 50 | { |
51 | directoriesById.Add(targetDir.Id.Id, targetDir); | 51 | directoryIds.Add(targetDir.Id.Id); |
52 | this.Section.AddSymbol(targetDir); | 52 | this.Section.AddSymbol(targetDir); |
53 | } | 53 | } |
54 | } | 54 | } |
55 | 55 | ||
56 | private void EnsureStandardDirectoryAdded(Dictionary<string, DirectorySymbol> directoriesById, string directoryId, SourceLineNumber sourceLineNumbers) | 56 | private void EnsureStandardDirectoryAdded(ISet<string> directoryIds, string directoryId, SourceLineNumber sourceLineNumbers) |
57 | { | 57 | { |
58 | if (!directoriesById.ContainsKey(directoryId) && WindowsInstallerStandard.TryGetStandardDirectory(directoryId, out var standardDirectory)) | 58 | if (!directoryIds.Contains(directoryId) && WindowsInstallerStandard.TryGetStandardDirectory(directoryId, out var standardDirectory)) |
59 | { | 59 | { |
60 | var parentDirectoryId = this.GetStandardDirectoryParent(directoryId); | 60 | var parentDirectoryId = this.GetStandardDirectoryParent(directoryId); |
61 | 61 | ||
@@ -65,12 +65,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
65 | ParentDirectoryRef = parentDirectoryId, | 65 | ParentDirectoryRef = parentDirectoryId, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | directoriesById.Add(directory.Id.Id, directory); | 68 | directoryIds.Add(directory.Id.Id); |
69 | this.Section.AddSymbol(directory); | 69 | this.Section.AddSymbol(directory); |
70 | 70 | ||
71 | if (!String.IsNullOrEmpty(parentDirectoryId)) | 71 | if (!String.IsNullOrEmpty(parentDirectoryId)) |
72 | { | 72 | { |
73 | this.EnsureStandardDirectoryAdded(directoriesById, parentDirectoryId, sourceLineNumbers); | 73 | this.EnsureStandardDirectoryAdded(directoryIds, parentDirectoryId, sourceLineNumbers); |
74 | } | 74 | } |
75 | } | 75 | } |
76 | } | 76 | } |
diff --git a/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs b/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs index 1c2ca8eb..a4b2bee3 100644 --- a/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs +++ b/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs | |||
@@ -38,10 +38,17 @@ namespace WixToolset.Core.Link | |||
38 | /// </summary> | 38 | /// </summary> |
39 | public IEnumerable<SymbolWithSection> PossibleConflicts { get; private set; } | 39 | public IEnumerable<SymbolWithSection> PossibleConflicts { get; private set; } |
40 | 40 | ||
41 | /// <summary> | ||
42 | /// Gets the collection of redundant symbols that should not be included | ||
43 | /// in the final output. | ||
44 | /// </summary> | ||
45 | public ISet<IntermediateSymbol> RedundantSymbols { get; private set; } | ||
46 | |||
41 | public void Execute() | 47 | public void Execute() |
42 | { | 48 | { |
43 | var symbolsByName = new Dictionary<string, SymbolWithSection>(); | 49 | var symbolsByName = new Dictionary<string, SymbolWithSection>(); |
44 | var possibleConflicts = new HashSet<SymbolWithSection>(); | 50 | var possibleConflicts = new HashSet<SymbolWithSection>(); |
51 | var redundantSymbols = new HashSet<IntermediateSymbol>(); | ||
45 | 52 | ||
46 | if (!Enum.TryParse(this.ExpectedOutputType.ToString(), out SectionType expectedEntrySectionType)) | 53 | if (!Enum.TryParse(this.ExpectedOutputType.ToString(), out SectionType expectedEntrySectionType)) |
47 | { | 54 | { |
@@ -91,13 +98,13 @@ namespace WixToolset.Core.Link | |||
91 | // Ensure identical symbol's symbol is marked redundant to ensure (should the symbol be | 98 | // Ensure identical symbol's symbol is marked redundant to ensure (should the symbol be |
92 | // referenced into the final output) it will not add duplicate primary keys during | 99 | // referenced into the final output) it will not add duplicate primary keys during |
93 | // the .IDT importing. | 100 | // the .IDT importing. |
94 | //symbol.Row.Redundant = true; - TODO: remove this | ||
95 | existingSymbol.AddRedundant(symbolWithSection); | 101 | existingSymbol.AddRedundant(symbolWithSection); |
102 | redundantSymbols.Add(symbolWithSection.Symbol); | ||
96 | } | 103 | } |
97 | else | 104 | else |
98 | { | 105 | { |
99 | existingSymbol.AddPossibleConflict(symbolWithSection); | 106 | existingSymbol.AddPossibleConflict(symbolWithSection); |
100 | possibleConflicts.Add(existingSymbol); | 107 | possibleConflicts.Add(symbolWithSection); |
101 | } | 108 | } |
102 | } | 109 | } |
103 | } | 110 | } |
@@ -105,6 +112,7 @@ namespace WixToolset.Core.Link | |||
105 | 112 | ||
106 | this.SymbolsByName = symbolsByName; | 113 | this.SymbolsByName = symbolsByName; |
107 | this.PossibleConflicts = possibleConflicts; | 114 | this.PossibleConflicts = possibleConflicts; |
115 | this.RedundantSymbols = redundantSymbols; | ||
108 | } | 116 | } |
109 | } | 117 | } |
110 | } | 118 | } |
diff --git a/src/WixToolset.Core/Link/IntermediateSymbolExtensions.cs b/src/WixToolset.Core/Link/IntermediateSymbolExtensions.cs index db53f1ce..cbf48abe 100644 --- a/src/WixToolset.Core/Link/IntermediateSymbolExtensions.cs +++ b/src/WixToolset.Core/Link/IntermediateSymbolExtensions.cs | |||
@@ -1,4 +1,4 @@ | |||
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 | ||
3 | namespace WixToolset.Core.Link | 3 | namespace WixToolset.Core.Link |
4 | { | 4 | { |
@@ -9,10 +9,10 @@ namespace WixToolset.Core.Link | |||
9 | public static bool IsIdentical(this IntermediateSymbol first, IntermediateSymbol second) | 9 | public static bool IsIdentical(this IntermediateSymbol first, IntermediateSymbol second) |
10 | { | 10 | { |
11 | var identical = (first.Definition.Type == second.Definition.Type && | 11 | var identical = (first.Definition.Type == second.Definition.Type && |
12 | first.Definition.Name == second.Definition.Name && | 12 | (first.Definition.Type != SymbolDefinitionType.MustBeFromAnExtension || first.Definition.Name == second.Definition.Name) && |
13 | first.Definition.FieldDefinitions.Length == second.Definition.FieldDefinitions.Length); | 13 | first.Definition.FieldDefinitions.Length == second.Definition.FieldDefinitions.Length); |
14 | 14 | ||
15 | for (int i = 0; identical && i < first.Definition.FieldDefinitions.Length; ++i) | 15 | for (var i = 0; identical && i < first.Definition.FieldDefinitions.Length; ++i) |
16 | { | 16 | { |
17 | var firstField = first[i]; | 17 | var firstField = first[i]; |
18 | var secondField = second[i]; | 18 | var secondField = second[i]; |
diff --git a/src/WixToolset.Core/Link/ResolveReferencesCommand.cs b/src/WixToolset.Core/Link/ResolveReferencesCommand.cs index 90b61e8b..2bdd5646 100644 --- a/src/WixToolset.Core/Link/ResolveReferencesCommand.cs +++ b/src/WixToolset.Core/Link/ResolveReferencesCommand.cs | |||
@@ -170,9 +170,9 @@ namespace WixToolset.Core.Link | |||
170 | case AccessModifier.Public: | 170 | case AccessModifier.Public: |
171 | return true; | 171 | return true; |
172 | case AccessModifier.Internal: | 172 | case AccessModifier.Internal: |
173 | return symbolWithSection.Section.CompilationId.Equals(referencingSection.CompilationId) || (null != symbolWithSection.Section.LibraryId && symbolWithSection.Section.LibraryId.Equals(referencingSection.LibraryId)); | 173 | return symbolWithSection.Section.CompilationId == referencingSection.CompilationId || (null != symbolWithSection.Section.LibraryId && symbolWithSection.Section.LibraryId == referencingSection.LibraryId); |
174 | case AccessModifier.Protected: | 174 | case AccessModifier.Protected: |
175 | return symbolWithSection.Section.CompilationId.Equals(referencingSection.CompilationId); | 175 | return symbolWithSection.Section.CompilationId == referencingSection.CompilationId; |
176 | case AccessModifier.Private: | 176 | case AccessModifier.Private: |
177 | return referencingSection == symbolWithSection.Section; | 177 | return referencingSection == symbolWithSection.Section; |
178 | default: | 178 | default: |
diff --git a/src/WixToolset.Core/Linker.cs b/src/WixToolset.Core/Linker.cs index e9f9554c..431ba4c7 100644 --- a/src/WixToolset.Core/Linker.cs +++ b/src/WixToolset.Core/Linker.cs | |||
@@ -226,6 +226,11 @@ namespace WixToolset.Core | |||
226 | 226 | ||
227 | foreach (var symbol in section.Symbols) | 227 | foreach (var symbol in section.Symbols) |
228 | { | 228 | { |
229 | if (find.RedundantSymbols.Contains(symbol)) | ||
230 | { | ||
231 | continue; | ||
232 | } | ||
233 | |||
229 | var copySymbol = true; // by default, copy symbols. | 234 | var copySymbol = true; // by default, copy symbols. |
230 | 235 | ||
231 | // handle special tables | 236 | // handle special tables |
diff --git a/src/test/WixToolsetTest.CoreIntegration/DirectoryFixture.cs b/src/test/WixToolsetTest.CoreIntegration/DirectoryFixture.cs index 83f2f2bb..2d6e4802 100644 --- a/src/test/WixToolsetTest.CoreIntegration/DirectoryFixture.cs +++ b/src/test/WixToolsetTest.CoreIntegration/DirectoryFixture.cs | |||
@@ -85,5 +85,44 @@ namespace WixToolsetTest.CoreIntegration | |||
85 | }, dirSymbols.Select(d => d.Id.Id).ToArray()); | 85 | }, dirSymbols.Select(d => d.Id.Id).ToArray()); |
86 | } | 86 | } |
87 | } | 87 | } |
88 | |||
89 | [Fact] | ||
90 | public void CanGetDuplicateDir() | ||
91 | { | ||
92 | var folder = TestData.Get(@"TestData"); | ||
93 | |||
94 | using (var fs = new DisposableFileSystem()) | ||
95 | { | ||
96 | var baseFolder = fs.GetFolder(); | ||
97 | var intermediateFolder = Path.Combine(baseFolder, "obj"); | ||
98 | var msiPath = Path.Combine(baseFolder, @"bin\test.msi"); | ||
99 | |||
100 | var result = WixRunner.Execute(new[] | ||
101 | { | ||
102 | "build", | ||
103 | "-arch", "x64", | ||
104 | Path.Combine(folder, "DuplicateDir", "DuplicateDir.wxs"), | ||
105 | Path.Combine(folder, "ProductWithComponentGroupRef", "Product.wxs"), | ||
106 | "-bindpath", Path.Combine(folder, "SingleFile", "data"), | ||
107 | "-intermediateFolder", intermediateFolder, | ||
108 | "-o", msiPath | ||
109 | }); | ||
110 | |||
111 | result.AssertSuccess(); | ||
112 | |||
113 | var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wixpdb")); | ||
114 | var section = intermediate.Sections.Single(); | ||
115 | |||
116 | var dirSymbols = section.Symbols.OfType<WixToolset.Data.Symbols.DirectorySymbol>().ToList(); | ||
117 | Assert.Equal(new[] | ||
118 | { | ||
119 | "dirZsSsu81KcG46xXTwc4mTSZO5Zx4", | ||
120 | "INSTALLFOLDER", | ||
121 | "ProgramFiles6432Folder", | ||
122 | "ProgramFiles64Folder", | ||
123 | "TARGETDIR" | ||
124 | }, dirSymbols.Select(d => d.Id.Id).ToArray()); | ||
125 | } | ||
126 | } | ||
88 | } | 127 | } |
89 | } | 128 | } |
diff --git a/src/test/WixToolsetTest.CoreIntegration/TestData/DuplicateDir/DuplicateDir.wxs b/src/test/WixToolsetTest.CoreIntegration/TestData/DuplicateDir/DuplicateDir.wxs new file mode 100644 index 00000000..ffee969d --- /dev/null +++ b/src/test/WixToolsetTest.CoreIntegration/TestData/DuplicateDir/DuplicateDir.wxs | |||
@@ -0,0 +1,25 @@ | |||
1 | <?xml version="1.0" encoding="utf-8" ?> | ||
2 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | ||
3 | <Fragment> | ||
4 | <ComponentGroup Id="ProductComponents"> | ||
5 | <ComponentGroupRef Id="GroupA" /> | ||
6 | <ComponentGroupRef Id="GroupB" /> | ||
7 | </ComponentGroup> | ||
8 | </Fragment> | ||
9 | |||
10 | <Fragment> | ||
11 | <ComponentGroup Id="GroupA" Directory="INSTALLFOLDER:\dupe"> | ||
12 | <Component> | ||
13 | <File Name="a.txt" Source="test.txt" /> | ||
14 | </Component> | ||
15 | </ComponentGroup> | ||
16 | </Fragment> | ||
17 | |||
18 | <Fragment> | ||
19 | <ComponentGroup Id="GroupB" Directory="INSTALLFOLDER:\dupe"> | ||
20 | <Component> | ||
21 | <File Name="b.txt" Source="test.txt" /> | ||
22 | </Component> | ||
23 | </ComponentGroup> | ||
24 | </Fragment> | ||
25 | </Wix> | ||