Skip to content

Commit

Permalink
Magicked files in modules need complex references.
Browse files Browse the repository at this point in the history
Magic files (naked `File`s and `Files`) that are direct children of a
`Module` need complex references from the generated component to that
module, to ensure that they're wired up correctly as module components.

Fixes wixtoolset/issues#8860
  • Loading branch information
barnson authored and robmen committed Dec 27, 2024
1 parent 5dc8c89 commit 28a2c0e
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 10 deletions.
8 changes: 8 additions & 0 deletions src/api/wix/WixToolset.Data/Symbols/HarvestFilesSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public static partial class SymbolDefinitions
new IntermediateFieldDefinition(nameof(HarvestFilesSymbolFields.ComplexReferenceParentType), IntermediateFieldType.String),
new IntermediateFieldDefinition(nameof(HarvestFilesSymbolFields.ParentId), IntermediateFieldType.String),
new IntermediateFieldDefinition(nameof(HarvestFilesSymbolFields.SourcePath), IntermediateFieldType.String),
new IntermediateFieldDefinition(nameof(HarvestFilesSymbolFields.ModuleLanguage), IntermediateFieldType.String),
},
typeof(HarvestFilesSymbol));
}
Expand All @@ -31,6 +32,7 @@ public enum HarvestFilesSymbolFields
ComplexReferenceParentType,
ParentId,
SourcePath,
ModuleLanguage,
}

public class HarvestFilesSymbol : IntermediateSymbol
Expand Down Expand Up @@ -80,5 +82,11 @@ public string SourcePath
get => (string)this.Fields[(int)HarvestFilesSymbolFields.SourcePath];
set => this.Set((int)HarvestFilesSymbolFields.SourcePath, value);
}

public string ModuleLanguage
{
get => (string)this.Fields[(int)HarvestFilesSymbolFields.ModuleLanguage];
set => this.Set((int)HarvestFilesSymbolFields.ModuleLanguage, value);
}
}
}
8 changes: 7 additions & 1 deletion src/wix/WixToolset.Core/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5689,7 +5689,12 @@ private void ParseNakedFileElement(XElement node, ComplexReferenceParentType par

this.ParseFileElementChildren(node, fileSymbol, keyPath, win64);

if (ComplexReferenceParentType.Unknown != parentType && null != parentId) // if parent was provided, add a complex reference to that.
// if this is a module, automatically add this component to the references to ensure it gets in the ModuleComponents table
if (this.compilingModule)
{
this.Core.CreateComplexReference(sourceLineNumbers, ComplexReferenceParentType.Module, this.activeName, this.activeLanguage, ComplexReferenceChildType.Component, fileSymbol.Id.Id, false);
}
else if (ComplexReferenceParentType.Unknown != parentType && null != parentId) // if parent was provided, add a complex reference to that.
{
// If the naked file's component is defined directly under a feature, then mark the complex reference primary.
this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.Component, fileSymbol.Id.Id, ComplexReferenceParentType.Feature == parentType);
Expand Down Expand Up @@ -5790,6 +5795,7 @@ private void ParseFilesElement(XElement node, ComplexReferenceParentType parentT
ComplexReferenceParentType = parentType.ToString(),
ParentId = parentId,
SourcePath = sourcePath,
ModuleLanguage = this.compilingModule ? this.activeLanguage : null,
});
}

Expand Down
9 changes: 7 additions & 2 deletions src/wix/WixToolset.Core/HarvestFilesCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,15 @@ private void HarvestFiles(HarvestFilesSymbol harvestFile, IntermediateSection se
Win64 = this.Context.Platform == Platform.ARM64 || this.Context.Platform == Platform.X64,
});

if (Enum.TryParse<ComplexReferenceParentType>(harvestFile.ComplexReferenceParentType, out var parentType)
// if this is a module, automatically add this component to the references to ensure it gets in the ModuleComponents table
if (!String.IsNullOrEmpty(harvestFile.ModuleLanguage))
{
this.ParseHelper.CreateComplexReference(section, harvestFile.SourceLineNumbers, ComplexReferenceParentType.Module, harvestFile.ParentId, harvestFile.ModuleLanguage, ComplexReferenceChildType.Component, id.Id, false);
}
else if (Enum.TryParse<ComplexReferenceParentType>(harvestFile.ComplexReferenceParentType, out var parentType)
&& ComplexReferenceParentType.Unknown != parentType && null != harvestFile.ParentId)
{
// If the parent was provided, add a complex reference to that, and, if
// If the parent was provided, add a complex reference to that, and, if
// the Files is under a feature, then mark the complex reference primary.
this.ParseHelper.CreateComplexReference(section, harvestFile.SourceLineNumbers, parentType, harvestFile.ParentId, null, ComplexReferenceChildType.Component, id.Id, ComplexReferenceParentType.Feature == parentType);
}
Expand Down
31 changes: 25 additions & 6 deletions src/wix/test/WixToolsetTest.CoreIntegration/HarvestFilesFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace WixToolsetTest.CoreIntegration
using System.Linq;
using WixInternal.Core.TestPackage;
using WixInternal.TestSupport;
using WixToolset.Data.WindowsInstaller;
using Xunit;

public class HarvestFilesFixture
Expand Down Expand Up @@ -225,16 +226,34 @@ public void CanHarvestFilesInFragments()
[Fact]
public void CanHarvestFilesInModules()
{
var expected = new[]
var expectedFilesAndTargetPaths = new[]
{
@"flsgrgAVAsCQ8tCCxfnbBNis66623c.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\test1.txt",
@"flsBvxG729t7hKBa4KOmfvNMPptZkM.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\test4.txt",
@"flsDBWSWjpVSU3Zs33bREsJa2ygSQM.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\test2.txt",
@"flsehdwEdXusUijRShuTszSxwf8joA.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\test3.txt",
@"flsBvxG729t7hKBa4KOmfvNMPptZkM.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\test4.txt",
@"flsgrgAVAsCQ8tCCxfnbBNis66623c.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\test1.txt",
@"flskqOUVMfAE13k2h.ZkPhurwO4Y1c.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\notatest.txt",
};

Build("Module.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected), isPackage: false);
var expectedModuleComponents = new[]
{
"ModuleComponents:flsBvxG729t7hKBa4KOmfvNMPptZkM.E535B765_1019_4A4F_B3EA_AE28870E6D73\tMergeModule.E535B765_1019_4A4F_B3EA_AE28870E6D73\t1033",
"ModuleComponents:flsDBWSWjpVSU3Zs33bREsJa2ygSQM.E535B765_1019_4A4F_B3EA_AE28870E6D73\tMergeModule.E535B765_1019_4A4F_B3EA_AE28870E6D73\t1033",
"ModuleComponents:flsehdwEdXusUijRShuTszSxwf8joA.E535B765_1019_4A4F_B3EA_AE28870E6D73\tMergeModule.E535B765_1019_4A4F_B3EA_AE28870E6D73\t1033",
"ModuleComponents:flsgrgAVAsCQ8tCCxfnbBNis66623c.E535B765_1019_4A4F_B3EA_AE28870E6D73\tMergeModule.E535B765_1019_4A4F_B3EA_AE28870E6D73\t1033",
"ModuleComponents:flskqOUVMfAE13k2h.ZkPhurwO4Y1c.E535B765_1019_4A4F_B3EA_AE28870E6D73\tMergeModule.E535B765_1019_4A4F_B3EA_AE28870E6D73\t1033",
};

Build("Module.wxs", (msiPath, _) => AssertModuleComponentsFileIdsAndTargetPaths(msiPath, expectedFilesAndTargetPaths, expectedModuleComponents), isMsi: false);

static void AssertModuleComponentsFileIdsAndTargetPaths(string msiPath, string[] expectedFilesAndTargetPaths, string[] expectedModuleComponents)
{
AssertFileIdsAndTargetPaths(msiPath, expectedFilesAndTargetPaths);

var query = Query.QueryDatabase(msiPath, new[] { "ModuleComponents" });

Assert.Equal(expectedModuleComponents, query);
}
}

[Fact]
Expand Down Expand Up @@ -346,7 +365,7 @@ private static void AssertFileIdsAndTargetPaths(string msiPath, string[] expecte
Assert.Equal(sortedExpected, actual);
}

private static void Build(string file, Action<string, WixRunnerResult> tester, bool isPackage = true, bool warningsAsErrors = true, bool addUnnamedBindPath = false, params string[] additionalCommandLineArguments)
private static void Build(string file, Action<string, WixRunnerResult> tester, bool isMsi = true, bool warningsAsErrors = true, bool addUnnamedBindPath = false, params string[] additionalCommandLineArguments)
{
var folder = TestData.Get("TestData", "HarvestFiles");

Expand All @@ -355,7 +374,7 @@ private static void Build(string file, Action<string, WixRunnerResult> tester, b
var baseFolder = fs.GetFolder();
var intermediateFolder = Path.Combine(baseFolder, "obj");
var binFolder = Path.Combine(baseFolder, "bin");
var msiPath = Path.Combine(binFolder, isPackage ? "test.msi" : "test.msm");
var msiPath = Path.Combine(binFolder, isMsi ? "test.msi" : "test.msm");

var arguments = new List<string>()
{
Expand Down
18 changes: 17 additions & 1 deletion src/wix/test/WixToolsetTest.CoreIntegration/NakedFileFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace WixToolsetTest.CoreIntegration
{
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -82,6 +83,14 @@ public void CanBuildNakedFilesInModule()
var rows = BuildAndQueryComponentAndFileTables("Module.wxs", isPackage: false);

AssertFileComponentIds(2, rows);

var expectedModuleComponents = new[]
{
"ModuleComponents:FILE1.E535B765_1019_4A4F_B3EA_AE28870E6D73\tMergeModule.E535B765_1019_4A4F_B3EA_AE28870E6D73\t1033",
"ModuleComponents:FILE2.E535B765_1019_4A4F_B3EA_AE28870E6D73\tMergeModule.E535B765_1019_4A4F_B3EA_AE28870E6D73\t1033",
};

Assert.Equal(expectedModuleComponents, rows.Where(row => row.StartsWith("ModuleComponents:")));
}

[Fact]
Expand Down Expand Up @@ -215,7 +224,14 @@ private static string[] BuildAndQueryComponentAndFileTables(string file, bool is
{
result.AssertSuccess();

return Query.QueryDatabase(msiPath, new[] { "Component", "File" })
var tables = new List<string> { "Component", "File" };

if (!isPackage)
{
tables.Add("ModuleComponents");
}

return Query.QueryDatabase(msiPath, tables.ToArray())
.OrderBy(s => s)
.ToArray();
}
Expand Down

0 comments on commit 28a2c0e

Please sign in to comment.