Skip to content

Commit e804d30

Browse files
committed
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 wixtoolset/issues#8674
1 parent ce73352 commit e804d30

File tree

12 files changed

+99
-22
lines changed

12 files changed

+99
-22
lines changed

src/wix/WixToolset.Core/Compiler.cs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5348,7 +5348,7 @@ private YesNoType ParseFileElementAttributes(XElement node, string componentId,
53485348
}
53495349
}
53505350

5351-
if (null == id)
5351+
if (null == id && !isNakedFile)
53525352
{
53535353
id = this.Core.CreateIdentifier("fil", directoryId, name);
53545354
}
@@ -5610,8 +5610,6 @@ private void ParseNakedFileElement(XElement node, ComplexReferenceParentType par
56105610
string condition = null;
56115611
string subdirectory = null;
56125612

5613-
var keyPath = this.ParseFileElementAttributes(node, "@WixTemporaryComponentId", directoryId, diskId: CompilerConstants.IntegerNotSet, sourcePath, out var _, componentGuid: "*", isNakedFile: true, out var fileSymbol, out var assemblySymbol);
5614-
56155613
if (!this.Core.EncounteredError)
56165614
{
56175615
// Naked files have additional attributes to handle common component attributes.
@@ -5661,13 +5659,43 @@ private void ParseNakedFileElement(XElement node, ComplexReferenceParentType par
56615659

56625660
directoryId = this.HandleSubdirectory(sourceLineNumbers, node, directoryId, subdirectory, "Directory", "Subdirectory");
56635661

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)
56655693
{
56665694
ComponentId = "*",
56675695
DirectoryRef = directoryId,
56685696
Location = ComponentLocation.LocalOnly,
56695697
Condition = condition,
5670-
KeyPath = fileSymbol.Id.Id,
5698+
KeyPath = id.Id,
56715699
KeyPathType = ComponentKeyPathType.File,
56725700
DisableRegistryReflection = false,
56735701
NeverOverwrite = false,
@@ -5679,9 +5707,6 @@ private void ParseNakedFileElement(XElement node, ComplexReferenceParentType par
56795707
Win64 = win64,
56805708
});
56815709

5682-
fileSymbol.ComponentRef = fileSymbol.Id.Id;
5683-
this.Core.AddSymbol(fileSymbol);
5684-
56855710
if (assemblySymbol != null)
56865711
{
56875712
this.Core.AddSymbol(assemblySymbol);
@@ -5692,7 +5717,7 @@ private void ParseNakedFileElement(XElement node, ComplexReferenceParentType par
56925717
if (ComplexReferenceParentType.Unknown != parentType && null != parentId) // if parent was provided, add a complex reference to that.
56935718
{
56945719
// If the naked file's component is defined directly under a feature, then mark the complex reference primary.
5695-
this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.Component, fileSymbol.Id.Id, ComplexReferenceParentType.Feature == parentType);
5720+
this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.Component, id.Id, ComplexReferenceParentType.Feature == parentType);
56965721
}
56975722
}
56985723
}

src/wix/WixToolset.Core/Linker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ private void FlattenGroup(string parentTypeAndId, Stack<string> loopDetector, Di
716716
var childTypeAndId = this.CombineTypeAndId(wixComplexReferenceRow.ChildType, wixComplexReferenceRow.Child);
717717
if (loopDetector.Contains(childTypeAndId))
718718
{
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
720720
// loop for the error message. Start at the bottom of the stack and work the
721721
// way up to present the loop as a directed graph.
722722
var loop = String.Join(" -> ", loopDetector);

src/wix/test/WixToolsetTest.CoreIntegration/HarvestFilesFixture.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,41 @@ public void CanHarvestFilesInFiveLines()
291291
Build("PackageFiveLiner.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
292292
}
293293

294+
[Fact]
295+
public void CanHarvestFilesWithDuplicateNames()
296+
{
297+
var expectedFiles = new[]
298+
{
299+
"File:fls47G631z.20kTPzBwIPjGuWifsVo\tfls47G631z.20kTPzBwIPjGuWifsVo\tfile.x\t0\t\t\t512\t2",
300+
"File:flshOXYGoD0VHcQhrkIILRPNOVbYuM\tflshOXYGoD0VHcQhrkIILRPNOVbYuM\tfile.x\t0\t\t\t512\t1",
301+
"File:flsp2QdFvBeSwll1i5tN0jM72w3Hu4\tflsp2QdFvBeSwll1i5tN0jM72w3Hu4\tfile.x\t0\t\t\t512\t3",
302+
"File:flsqopW5ihQpwCTF7t_51GkHd4Hf6s\tflsqopW5ihQpwCTF7t_51GkHd4Hf6s\tfile.x\t0\t\t\t512\t4",
303+
};
304+
305+
var expectedFilesAndDirectories = new[]
306+
{
307+
@"fls47G631z.20kTPzBwIPjGuWifsVo=PFiles\Example Corporation MsiPackage\b\file.x",
308+
@"flshOXYGoD0VHcQhrkIILRPNOVbYuM=PFiles\Example Corporation MsiPackage\a\file.x",
309+
@"flsp2QdFvBeSwll1i5tN0jM72w3Hu4=PFiles\Example Corporation MsiPackage\c\file.x",
310+
@"flsqopW5ihQpwCTF7t_51GkHd4Hf6s=PFiles\Example Corporation MsiPackage\d\file.x",
311+
};
312+
313+
Build("DuplicateNames.wxs", (msiPath, result) => AssertFileAndComponentIdsAndTargetPaths(msiPath, result, expectedFiles, expectedFilesAndDirectories));
314+
}
315+
316+
private static void AssertFileAndComponentIdsAndTargetPaths(string msiPath, WixRunnerResult result, string[] expectedFiles, string[] expectedFilesAndDirectories)
317+
{
318+
result.AssertSuccess();
319+
320+
var files = Query.QueryDatabase(msiPath, new[] { "File" })
321+
.OrderBy(s => s)
322+
.ToArray();
323+
324+
Assert.Equal(expectedFiles, files);
325+
326+
AssertFileIdsAndTargetPaths(msiPath, expectedFilesAndDirectories);
327+
}
328+
294329
private static void AssertFileIdsAndTargetPaths(string msiPath, string[] expected)
295330
{
296331
var pkg = new WixToolset.Dtf.WindowsInstaller.Package.InstallPackage(msiPath,

src/wix/test/WixToolsetTest.CoreIntegration/NakedFileFixture.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,13 @@ public void CanBuildNakedFilesUnderPackage()
105105
AssertFileComponentIds(4, rows);
106106
}
107107

108+
[Fact]
109+
public void CanBuildNakedFilesUnderPackageWithDuplicateNames()
110+
{
111+
var rows = BuildAndQueryComponentAndFileTables("DuplicateNames.wxs");
112+
AssertFileComponentIds(5, rows);
113+
}
114+
108115
[Fact]
109116
public void CanBuildNakedFilesUnderPackageWithDefaultInstallFolder()
110117
{
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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>

src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/a/file.x

Whitespace-only changes.

src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/b/file.x

Whitespace-only changes.

src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/c/file.x

Whitespace-only changes.

src/wix/test/WixToolsetTest.CoreIntegration/TestData/HarvestFiles/dupes/d/file.x

Whitespace-only changes.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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>
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
22
<Package Name="MsiPackage" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
3-
<MajorUpgrade DowngradeErrorMessage="Downgrade error message." />
4-
5-
<File Directory="INSTALLFOLDER" Source="test.txt" />
6-
<File Directory="INSTALLFOLDER" Source="test.txt" Name="test2.txt" />
7-
<File Directory="INSTALLFOLDER" Source="test.txt" Name="test3.txt" />
8-
<File Directory="INSTALLFOLDER" Source="test.txt" Name="test4.txt" />
3+
<File Directory="INSTALLFOLDER" Subdirectory="X" Source="test.txt" />
4+
<File Directory="INSTALLFOLDER" Subdirectory="X" Source="test.txt" Name="test2.txt" />
5+
<File Directory="INSTALLFOLDER" Subdirectory="X3" Source="test.txt" Name="test3.txt" />
6+
<File Directory="INSTALLFOLDER" Subdirectory="X4" Source="test.txt" Name="test4.txt" />
97
</Package>
108
</Wix>
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
22
<Package Name="MsiPackage" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
3-
<MajorUpgrade DowngradeErrorMessage="Downgrade error message." />
4-
5-
<File Source="test.txt" />
6-
<File Source="test.txt" Name="test2.txt" />
7-
<File Source="test.txt" Name="test3.txt" />
8-
<File Source="test.txt" Name="test4.txt" />
3+
<File Subdirectory="X" Name="test.txt" Source="test.txt" />
4+
<File Subdirectory="X" Name="test2.txt" Source="test.txt" />
5+
<File Subdirectory="X3" Name="test3.txt" Source="test.txt" />
6+
<File Subdirectory="X4" Name="test4.txt" Source="test.txt" />
97
</Package>
108
</Wix>

0 commit comments

Comments
 (0)