aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Arnson <bob@firegiant.com>2024-08-03 16:37:31 -0400
committerRob Mensching <rob@firegiant.com>2024-12-28 19:39:41 -0800
commit720708fac9ea0109a9918611f69ebf6cc370bbeb (patch)
treead551594475fb783d42100f905256c071ed8ae88
parenta076b9d72486328d8dc95675daae417a3c07d6d6 (diff)
downloadwix-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
-rw-r--r--src/wix/WixToolset.Core/Compiler.cs43
-rw-r--r--src/wix/WixToolset.Core/Linker.cs2
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/HarvestFilesFixture.cs35
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/NakedFileFixture.cs7
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/DuplicateNames.wxs5
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/a/file.x0
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/b/file.x0
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/c/file.x0
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/d/file.x0
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/NakedFile/DuplicateNames.wxs9
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/NakedFile/Package.wxs10
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/NakedFile/PackageWithDefaultInstallFolder.wxs10
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>