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 /src | |
| parent | b00c72ed0ef19d2e46f60361fa06821b0bd5ec94 (diff) | |
| download | wix-0d1851c79901ba6ddbba9bb63f758760fe5be994.tar.gz wix-0d1851c79901ba6ddbba9bb63f758760fe5be994.tar.bz2 wix-0d1851c79901ba6ddbba9bb63f758760fe5be994.zip | |
Fix handling of duplicate directories
Diffstat (limited to 'src')
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> | ||
