diff options
author | Bob Arnson <bob@firegiant.com> | 2024-08-03 16:37:31 -0400 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2024-12-28 19:39:41 -0800 |
commit | 720708fac9ea0109a9918611f69ebf6cc370bbeb (patch) | |
tree | ad551594475fb783d42100f905256c071ed8ae88 | |
parent | a076b9d72486328d8dc95675daae417a3c07d6d6 (diff) | |
download | wix-720708fac9ea0109a9918611f69ebf6cc370bbeb.tar.gz wix-720708fac9ea0109a9918611f69ebf6cc370bbeb.tar.bz2 wix-720708fac9ea0109a9918611f69ebf6cc370bbeb.zip |
Ensure naked files take Subdirectory into account.
Naked files generated their ids using the attributes that are common to
both naked and clothed files. But naked files also support @Subdirectory
to magic up a subdirectory in a specified directory (@Directory) or the
default INSTALLFOLDER. That subdirectory needs to factor in to the
generated file id (which is then used as the component id too).
Without it, generated ids for files with the same name but from
different @Subdirectory values would be duplicated. (Authored file ids
must also continue to be supported.)
Naked files now generate different file and component ids. :(
Fixes https://github.com/wixtoolset/issues/issues/8674
12 files changed, 99 insertions, 22 deletions
diff --git a/src/wix/WixToolset.Core/Compiler.cs b/src/wix/WixToolset.Core/Compiler.cs index 3b3c62d4..069743aa 100644 --- a/src/wix/WixToolset.Core/Compiler.cs +++ b/src/wix/WixToolset.Core/Compiler.cs | |||
@@ -5348,7 +5348,7 @@ namespace WixToolset.Core | |||
5348 | } | 5348 | } |
5349 | } | 5349 | } |
5350 | 5350 | ||
5351 | if (null == id) | 5351 | if (null == id && !isNakedFile) |
5352 | { | 5352 | { |
5353 | id = this.Core.CreateIdentifier("fil", directoryId, name); | 5353 | id = this.Core.CreateIdentifier("fil", directoryId, name); |
5354 | } | 5354 | } |
@@ -5610,8 +5610,6 @@ namespace WixToolset.Core | |||
5610 | string condition = null; | 5610 | string condition = null; |
5611 | string subdirectory = null; | 5611 | string subdirectory = null; |
5612 | 5612 | ||
5613 | var keyPath = this.ParseFileElementAttributes(node, "@WixTemporaryComponentId", directoryId, diskId: CompilerConstants.IntegerNotSet, sourcePath, out var _, componentGuid: "*", isNakedFile: true, out var fileSymbol, out var assemblySymbol); | ||
5614 | |||
5615 | if (!this.Core.EncounteredError) | 5613 | if (!this.Core.EncounteredError) |
5616 | { | 5614 | { |
5617 | // Naked files have additional attributes to handle common component attributes. | 5615 | // Naked files have additional attributes to handle common component attributes. |
@@ -5661,13 +5659,43 @@ namespace WixToolset.Core | |||
5661 | 5659 | ||
5662 | directoryId = this.HandleSubdirectory(sourceLineNumbers, node, directoryId, subdirectory, "Directory", "Subdirectory"); | 5660 | directoryId = this.HandleSubdirectory(sourceLineNumbers, node, directoryId, subdirectory, "Directory", "Subdirectory"); |
5663 | 5661 | ||
5664 | this.Core.AddSymbol(new ComponentSymbol(sourceLineNumbers, fileSymbol.Id) | 5662 | var keyPath = this.ParseFileElementAttributes(node, "@WixTemporaryComponentId", directoryId, diskId: CompilerConstants.IntegerNotSet, sourcePath, out var _, componentGuid: "*", isNakedFile: true, out var fileSymbol, out var assemblySymbol); |
5663 | |||
5664 | // Now that we have all the data we need to generate a good id, do | ||
5665 | // so and create a file and component symbol with the right data. | ||
5666 | var id = fileSymbol.Id ?? this.Core.CreateIdentifier("nkf", directoryId, fileSymbol.Name, condition, win64.ToString()); | ||
5667 | |||
5668 | this.Core.AddSymbol(new FileSymbol(sourceLineNumbers, id) | ||
5669 | { | ||
5670 | ComponentRef = id.Id, | ||
5671 | Name = fileSymbol.Name, | ||
5672 | ShortName = fileSymbol.ShortName, | ||
5673 | FileSize = fileSymbol.FileSize, | ||
5674 | Version = fileSymbol.Version, | ||
5675 | Language = fileSymbol.Language, | ||
5676 | Attributes = fileSymbol.Attributes, | ||
5677 | DirectoryRef = fileSymbol.DirectoryRef, | ||
5678 | DiskId = fileSymbol.DiskId, | ||
5679 | Source = fileSymbol.Source, | ||
5680 | FontTitle = fileSymbol.FontTitle, | ||
5681 | SelfRegCost = fileSymbol.SelfRegCost, | ||
5682 | BindPath = fileSymbol.BindPath, | ||
5683 | PatchGroup = fileSymbol.PatchGroup, | ||
5684 | PatchAttributes = fileSymbol.PatchAttributes, | ||
5685 | RetainLengths = fileSymbol.RetainLengths, | ||
5686 | IgnoreOffsets = fileSymbol.IgnoreOffsets, | ||
5687 | IgnoreLengths = fileSymbol.IgnoreLengths, | ||
5688 | RetainOffsets = fileSymbol.RetainOffsets, | ||
5689 | SymbolPaths = fileSymbol.SymbolPaths, | ||
5690 | }); | ||
5691 | |||
5692 | this.Core.AddSymbol(new ComponentSymbol(sourceLineNumbers, id) | ||
5665 | { | 5693 | { |
5666 | ComponentId = "*", | 5694 | ComponentId = "*", |
5667 | DirectoryRef = directoryId, | 5695 | DirectoryRef = directoryId, |
5668 | Location = ComponentLocation.LocalOnly, | 5696 | Location = ComponentLocation.LocalOnly, |
5669 | Condition = condition, | 5697 | Condition = condition, |
5670 | KeyPath = fileSymbol.Id.Id, | 5698 | KeyPath = id.Id, |
5671 | KeyPathType = ComponentKeyPathType.File, | 5699 | KeyPathType = ComponentKeyPathType.File, |
5672 | DisableRegistryReflection = false, | 5700 | DisableRegistryReflection = false, |
5673 | NeverOverwrite = false, | 5701 | NeverOverwrite = false, |
@@ -5679,9 +5707,6 @@ namespace WixToolset.Core | |||
5679 | Win64 = win64, | 5707 | Win64 = win64, |
5680 | }); | 5708 | }); |
5681 | 5709 | ||
5682 | fileSymbol.ComponentRef = fileSymbol.Id.Id; | ||
5683 | this.Core.AddSymbol(fileSymbol); | ||
5684 | |||
5685 | if (assemblySymbol != null) | 5710 | if (assemblySymbol != null) |
5686 | { | 5711 | { |
5687 | this.Core.AddSymbol(assemblySymbol); | 5712 | this.Core.AddSymbol(assemblySymbol); |
@@ -5697,7 +5722,7 @@ namespace WixToolset.Core | |||
5697 | else if (ComplexReferenceParentType.Unknown != parentType && null != parentId) // if parent was provided, add a complex reference to that. | 5722 | else if (ComplexReferenceParentType.Unknown != parentType && null != parentId) // if parent was provided, add a complex reference to that. |
5698 | { | 5723 | { |
5699 | // If the naked file's component is defined directly under a feature, then mark the complex reference primary. | 5724 | // If the naked file's component is defined directly under a feature, then mark the complex reference primary. |
5700 | this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.Component, fileSymbol.Id.Id, ComplexReferenceParentType.Feature == parentType); | 5725 | this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.Component, id.Id, ComplexReferenceParentType.Feature == parentType); |
5701 | } | 5726 | } |
5702 | } | 5727 | } |
5703 | } | 5728 | } |
diff --git a/src/wix/WixToolset.Core/Linker.cs b/src/wix/WixToolset.Core/Linker.cs index 43a41eac..b10a12d8 100644 --- a/src/wix/WixToolset.Core/Linker.cs +++ b/src/wix/WixToolset.Core/Linker.cs | |||
@@ -716,7 +716,7 @@ namespace WixToolset.Core | |||
716 | var childTypeAndId = this.CombineTypeAndId(wixComplexReferenceRow.ChildType, wixComplexReferenceRow.Child); | 716 | var childTypeAndId = this.CombineTypeAndId(wixComplexReferenceRow.ChildType, wixComplexReferenceRow.Child); |
717 | if (loopDetector.Contains(childTypeAndId)) | 717 | if (loopDetector.Contains(childTypeAndId)) |
718 | { | 718 | { |
719 | // Create a comma delimited list of the references that participate in the | 719 | // Create an arrow-delimited list of the references that participate in the |
720 | // loop for the error message. Start at the bottom of the stack and work the | 720 | // loop for the error message. Start at the bottom of the stack and work the |
721 | // way up to present the loop as a directed graph. | 721 | // way up to present the loop as a directed graph. |
722 | var loop = String.Join(" -> ", loopDetector); | 722 | var loop = String.Join(" -> ", loopDetector); |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/HarvestFilesFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/HarvestFilesFixture.cs index 8e4964de..a8af2b4d 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/HarvestFilesFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/HarvestFilesFixture.cs | |||
@@ -355,6 +355,41 @@ namespace WixToolsetTest.CoreIntegration | |||
355 | }, additionalCommandLineArguments: "-v"); | 355 | }, additionalCommandLineArguments: "-v"); |
356 | } | 356 | } |
357 | 357 | ||
358 | [Fact] | ||
359 | public void CanHarvestFilesWithDuplicateNames() | ||
360 | { | ||
361 | var expectedFiles = new[] | ||
362 | { | ||
363 | "File:fls47G631z.20kTPzBwIPjGuWifsVo\tfls47G631z.20kTPzBwIPjGuWifsVo\tfile.x\t0\t\t\t512\t2", | ||
364 | "File:flshOXYGoD0VHcQhrkIILRPNOVbYuM\tflshOXYGoD0VHcQhrkIILRPNOVbYuM\tfile.x\t0\t\t\t512\t1", | ||
365 | "File:flsp2QdFvBeSwll1i5tN0jM72w3Hu4\tflsp2QdFvBeSwll1i5tN0jM72w3Hu4\tfile.x\t0\t\t\t512\t3", | ||
366 | "File:flsqopW5ihQpwCTF7t_51GkHd4Hf6s\tflsqopW5ihQpwCTF7t_51GkHd4Hf6s\tfile.x\t0\t\t\t512\t4", | ||
367 | }; | ||
368 | |||
369 | var expectedFilesAndDirectories = new[] | ||
370 | { | ||
371 | @"fls47G631z.20kTPzBwIPjGuWifsVo=PFiles\Example Corporation MsiPackage\b\file.x", | ||
372 | @"flshOXYGoD0VHcQhrkIILRPNOVbYuM=PFiles\Example Corporation MsiPackage\a\file.x", | ||
373 | @"flsp2QdFvBeSwll1i5tN0jM72w3Hu4=PFiles\Example Corporation MsiPackage\c\file.x", | ||
374 | @"flsqopW5ihQpwCTF7t_51GkHd4Hf6s=PFiles\Example Corporation MsiPackage\d\file.x", | ||
375 | }; | ||
376 | |||
377 | Build("DuplicateNames.wxs", (msiPath, result) => AssertFileAndComponentIdsAndTargetPaths(msiPath, result, expectedFiles, expectedFilesAndDirectories)); | ||
378 | } | ||
379 | |||
380 | private static void AssertFileAndComponentIdsAndTargetPaths(string msiPath, WixRunnerResult result, string[] expectedFiles, string[] expectedFilesAndDirectories) | ||
381 | { | ||
382 | result.AssertSuccess(); | ||
383 | |||
384 | var files = Query.QueryDatabase(msiPath, new[] { "File" }) | ||
385 | .OrderBy(s => s) | ||
386 | .ToArray(); | ||
387 | |||
388 | Assert.Equal(expectedFiles, files); | ||
389 | |||
390 | AssertFileIdsAndTargetPaths(msiPath, expectedFilesAndDirectories); | ||
391 | } | ||
392 | |||
358 | private static void AssertFileIdsAndTargetPaths(string msiPath, string[] expected) | 393 | private static void AssertFileIdsAndTargetPaths(string msiPath, string[] expected) |
359 | { | 394 | { |
360 | var pkg = new WixToolset.Dtf.WindowsInstaller.Package.InstallPackage(msiPath, | 395 | var pkg = new WixToolset.Dtf.WindowsInstaller.Package.InstallPackage(msiPath, |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/NakedFileFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/NakedFileFixture.cs index ae13421d..3142b9da 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/NakedFileFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/NakedFileFixture.cs | |||
@@ -115,6 +115,13 @@ namespace WixToolsetTest.CoreIntegration | |||
115 | } | 115 | } |
116 | 116 | ||
117 | [Fact] | 117 | [Fact] |
118 | public void CanBuildNakedFilesUnderPackageWithDuplicateNames() | ||
119 | { | ||
120 | var rows = BuildAndQueryComponentAndFileTables("DuplicateNames.wxs"); | ||
121 | AssertFileComponentIds(5, rows); | ||
122 | } | ||
123 | |||
124 | [Fact] | ||
118 | public void CanBuildNakedFilesUnderPackageWithDefaultInstallFolder() | 125 | public void CanBuildNakedFilesUnderPackageWithDefaultInstallFolder() |
119 | { | 126 | { |
120 | var rows = BuildAndQueryComponentAndFileTables("PackageWithDefaultInstallFolder.wxs"); | 127 | var rows = BuildAndQueryComponentAndFileTables("PackageWithDefaultInstallFolder.wxs"); |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/DuplicateNames.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/DuplicateNames.wxs new file mode 100644 index 00000000..c3b08b69 --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/DuplicateNames.wxs | |||
@@ -0,0 +1,5 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | ||
2 | <Package Name="MsiPackage" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a"> | ||
3 | <Files Include="dupes\**" /> | ||
4 | </Package> | ||
5 | </Wix> | ||
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/a/file.x b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/a/file.x new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/a/file.x | |||
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/b/file.x b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/b/file.x new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/b/file.x | |||
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/c/file.x b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/c/file.x new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/c/file.x | |||
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/d/file.x b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/d/file.x new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/d/file.x | |||
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/NakedFile/DuplicateNames.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/NakedFile/DuplicateNames.wxs new file mode 100644 index 00000000..edccc504 --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/NakedFile/DuplicateNames.wxs | |||
@@ -0,0 +1,9 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | ||
2 | <Package Name="GenManyComponents 5x1" Manufacturer="FireGiant" Version="1.0.0.0" UpgradeCode="b146c9a9-7184-413c-8ab2-b65ed869feb9"> | ||
3 | <File Subdirectory='0000' Name='0000.x' Source='$(sys.SOURCEFILEPATH)' /> | ||
4 | <File Subdirectory='0001' Name='0000.x' Source='$(sys.SOURCEFILEPATH)' /> | ||
5 | <File Subdirectory='0002' Name='0000.x' Source='$(sys.SOURCEFILEPATH)' /> | ||
6 | <File Subdirectory='0003' Name='0000.x' Source='$(sys.SOURCEFILEPATH)' /> | ||
7 | <File Subdirectory='0004' Name='0000.x' Source='$(sys.SOURCEFILEPATH)' /> | ||
8 | </Package> | ||
9 | </Wix> | ||
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/NakedFile/Package.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/NakedFile/Package.wxs index e5dd94e0..9ddd4787 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/NakedFile/Package.wxs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/NakedFile/Package.wxs | |||
@@ -1,10 +1,8 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | 1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> |
2 | <Package Name="MsiPackage" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a"> | 2 | <Package Name="MsiPackage" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a"> |
3 | <MajorUpgrade DowngradeErrorMessage="Downgrade error message." /> | 3 | <File Directory="INSTALLFOLDER" Subdirectory="X" Source="test.txt" /> |
4 | 4 | <File Directory="INSTALLFOLDER" Subdirectory="X" Source="test.txt" Name="test2.txt" /> | |
5 | <File Directory="INSTALLFOLDER" Source="test.txt" /> | 5 | <File Directory="INSTALLFOLDER" Subdirectory="X3" Source="test.txt" Name="test3.txt" /> |
6 | <File Directory="INSTALLFOLDER" Source="test.txt" Name="test2.txt" /> | 6 | <File Directory="INSTALLFOLDER" Subdirectory="X4" Source="test.txt" Name="test4.txt" /> |
7 | <File Directory="INSTALLFOLDER" Source="test.txt" Name="test3.txt" /> | ||
8 | <File Directory="INSTALLFOLDER" Source="test.txt" Name="test4.txt" /> | ||
9 | </Package> | 7 | </Package> |
10 | </Wix> | 8 | </Wix> |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/NakedFile/PackageWithDefaultInstallFolder.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/NakedFile/PackageWithDefaultInstallFolder.wxs index 824f3501..01ca7735 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/NakedFile/PackageWithDefaultInstallFolder.wxs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/NakedFile/PackageWithDefaultInstallFolder.wxs | |||
@@ -1,10 +1,8 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | 1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> |
2 | <Package Name="MsiPackage" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a"> | 2 | <Package Name="MsiPackage" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a"> |
3 | <MajorUpgrade DowngradeErrorMessage="Downgrade error message." /> | 3 | <File Subdirectory="X" Name="test.txt" Source="test.txt" /> |
4 | 4 | <File Subdirectory="X" Name="test2.txt" Source="test.txt" /> | |
5 | <File Source="test.txt" /> | 5 | <File Subdirectory="X3" Name="test3.txt" Source="test.txt" /> |
6 | <File Source="test.txt" Name="test2.txt" /> | 6 | <File Subdirectory="X4" Name="test4.txt" Source="test.txt" /> |
7 | <File Source="test.txt" Name="test3.txt" /> | ||
8 | <File Source="test.txt" Name="test4.txt" /> | ||
9 | </Package> | 7 | </Package> |
10 | </Wix> | 8 | </Wix> |