Provide a default INSTALLFOLDER.
If INSTALLFOLDER is referenced and not defined, define one with reasonable default values. Implements WIP https://github.com/wixtoolset/issues/issues/7588.
Bob Arnson committed
Jul 29, 2023 at 19:03 UTC
f4a0522fde6066c76e771f6be381bf9e658b875a
6 files changed
+157
-40
src/wix/WixToolset.Core/AssignDefaultFeatureCommand.cs
+39
-27
@@ -3,55 +3,67 @@
3
namespace WixToolset.Core
4
{
5
using System.Collections.Generic;
6
- using System.ComponentModel;
6
using System.Linq;
7
+ using WixToolset.Core.Link;
8
using WixToolset.Data;
9
using WixToolset.Data.Symbols;
10
11
internal class AssignDefaultFeatureCommand
12
{
13
- public AssignDefaultFeatureCommand(IntermediateSection entrySection, IEnumerable<IntermediateSection> sections)
13
+ public AssignDefaultFeatureCommand(FindEntrySectionAndLoadSymbolsCommand find, List<IntermediateSection> sections)
14
{
15
- this.EntrySection = entrySection;
15
+ this.Find = find;
16
this.Sections = sections;
17
}
18
19
- public IntermediateSection EntrySection { get; }
20
-
19
public IEnumerable<IntermediateSection> Sections { get; }
20
21
+ public FindEntrySectionAndLoadSymbolsCommand Find { get; }
22
+
23
public void Execute()
24
{
25
- foreach (var section in this.Sections)
25
+ if (this.Find.EntrySection.Type == SectionType.Package
26
+ && !this.Sections.Where(s => s.Id != WixStandardLibraryIdentifiers.DefaultFeatureName)
27
+ .SelectMany(s => s.Symbols).OfType<FeatureSymbol>().Any())
28
{
27
- var components = section.Symbols.OfType<ComponentSymbol>().ToList();
28
- foreach (var component in components)
29
+ var addedToDefaultFeature = false;
30
+
31
+ foreach (var section in this.Sections)
32
{
30
- this.EntrySection.AddSymbol(new WixComplexReferenceSymbol(component.SourceLineNumbers)
33
+ var components = section.Symbols.OfType<ComponentSymbol>().ToList();
34
+ foreach (var component in components)
35
{
32
- Parent = WixStandardLibraryIdentifiers.DefaultFeatureName,
33
- ParentType = ComplexReferenceParentType.Feature,
34
- ParentLanguage = null,
35
- Child = component.Id.Id,
36
- ChildType = ComplexReferenceChildType.Component,
37
- IsPrimary = true,
38
- });
36
+ this.Find.EntrySection.AddSymbol(new WixComplexReferenceSymbol(component.SourceLineNumbers)
37
+ {
38
+ Parent = WixStandardLibraryIdentifiers.DefaultFeatureName,
39
+ ParentType = ComplexReferenceParentType.Feature,
40
+ ParentLanguage = null,
41
+ Child = component.Id.Id,
42
+ ChildType = ComplexReferenceChildType.Component,
43
+ IsPrimary = true,
44
+ });
45
+
46
+ this.Find.EntrySection.AddSymbol(new WixGroupSymbol(component.SourceLineNumbers)
47
+ {
48
+ ParentId = WixStandardLibraryIdentifiers.DefaultFeatureName,
49
+ ParentType = ComplexReferenceParentType.Feature,
50
+ ChildId = component.Id.Id,
51
+ ChildType = ComplexReferenceChildType.Component,
52
+ });
53
40
- this.EntrySection.AddSymbol(new WixGroupSymbol(component.SourceLineNumbers)
54
+ addedToDefaultFeature = true;
55
+ }
56
+ }
57
+
58
+ if (addedToDefaultFeature)
59
+ {
60
+ this.Find.EntrySection.AddSymbol(new WixSimpleReferenceSymbol()
61
{
42
- ParentId = WixStandardLibraryIdentifiers.DefaultFeatureName,
43
- ParentType = ComplexReferenceParentType.Feature,
44
- ChildId = component.Id.Id,
45
- ChildType = ComplexReferenceChildType.Component,
62
+ Table = "Feature",
63
+ PrimaryKeys = WixStandardLibraryIdentifiers.DefaultFeatureName,
64
});
65
}
66
}
49
-
50
- this.EntrySection.AddSymbol(new WixSimpleReferenceSymbol()
51
- {
52
- Table = "Feature",
53
- PrimaryKeys = WixStandardLibraryIdentifiers.DefaultFeatureName,
54
- });
67
}
68
}
69
}
src/wix/WixToolset.Core/Link/AddDefaultSymbolsCommand.cs
new
+69
@@ -0,0 +1,69 @@
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
+
3
+namespace WixToolset.Core.Link
4
+{
5
+ using System.Collections.Generic;
6
+ using System.Linq;
7
+ using WixToolset.Data;
8
+ using WixToolset.Data.Symbols;
9
+
10
+ internal class AddDefaultSymbolsCommand
11
+ {
12
+ public static readonly string WixStandardInstallFolder = "INSTALLFOLDER";
13
+ public static readonly string WixStandardInstallFolderParent = "ProgramFiles6432Folder";
14
+ public static readonly string WixStandardInstallFolderReference = "Directory:INSTALLFOLDER";
15
+
16
+ public AddDefaultSymbolsCommand(FindEntrySectionAndLoadSymbolsCommand find, IList<IntermediateSection> sections)
17
+ {
18
+ this.Find = find;
19
+ this.Sections = sections;
20
+ }
21
+
22
+ public IList<IntermediateSection> Sections { get; }
23
+
24
+ public FindEntrySectionAndLoadSymbolsCommand Find { get; }
25
+
26
+ public void Execute()
27
+ {
28
+ if (this.Find.EntrySection.Type != SectionType.Package)
29
+ {
30
+ // Only packages...for now.
31
+ return;
32
+ }
33
+
34
+ if (!this.Find.SymbolsByName.ContainsKey(WixStandardInstallFolderReference))
35
+ {
36
+ var sourceLineNumber = new SourceLineNumber("DefaultInstallFolder");
37
+
38
+ this.AddSymbolsToNewSection(WixStandardInstallFolder,
39
+ new DirectorySymbol(sourceLineNumber, new Identifier(AccessModifier.Global, WixStandardInstallFolder))
40
+ {
41
+ ParentDirectoryRef = WixStandardInstallFolderParent,
42
+ Name = "!(bind.Property.Manufacturer) !(bind.Property.ProductName)",
43
+ SourceName = ".",
44
+ },
45
+ new WixSimpleReferenceSymbol(sourceLineNumber, new Identifier(AccessModifier.Global, WixStandardInstallFolder))
46
+ {
47
+ Table = "Directory",
48
+ PrimaryKeys = WixStandardInstallFolderParent,
49
+ }
50
+ );
51
+ }
52
+ }
53
+
54
+ private void AddSymbolsToNewSection(string sectionId, params IntermediateSymbol[] symbols)
55
+ {
56
+ var section = new IntermediateSection(sectionId, SectionType.Fragment);
57
+ this.Sections.Add(section);
58
+
59
+ foreach (var symbol in symbols)
60
+ {
61
+ section.AddSymbol(symbol);
62
+
63
+ var symbolWithSection = new SymbolWithSection(section, symbol);
64
+ var fullName = symbolWithSection.GetFullName();
65
+ this.Find.SymbolsByName.Add(fullName, symbolWithSection);
66
+ }
67
+ }
68
+ }
69
+}
src/wix/WixToolset.Core/Linker.cs
+10
-4
@@ -126,11 +126,17 @@ namespace WixToolset.Core
126
}
127
}
128
129
- // If there are no authored features, create a default feature and assign the components to it.
130
- if (find.EntrySection.Type == SectionType.Package
131
- && !sections.Where(s => s.Id != WixStandardLibraryIdentifiers.DefaultFeatureName).SelectMany(s => s.Symbols).OfType<FeatureSymbol>().Any())
129
+ // Add default symbols that need a bit more intelligence than just being
130
+ // included in the standard library.
131
{
133
- var command = new AssignDefaultFeatureCommand(find.EntrySection, sections);
132
+ var command = new AddDefaultSymbolsCommand(find, sections);
133
+ command.Execute();
134
+ }
135
+
136
+ // If there are no authored features, create a default feature and assign
137
+ // the components to it.
138
+ {
139
+ var command = new AssignDefaultFeatureCommand(find, sections);
140
command.Execute();
141
}
142
src/wix/test/WixToolsetTest.CoreIntegration/DirectoryFixture.cs
+38
@@ -13,6 +13,44 @@ namespace WixToolsetTest.CoreIntegration
13
14
public class DirectoryFixture
15
{
16
+ [Fact]
17
+ public void CanGetDefaultInstallFolder()
18
+ {
19
+ var folder = TestData.Get(@"TestData\SingleFile");
20
+
21
+ using (var fs = new DisposableFileSystem())
22
+ {
23
+ var baseFolder = fs.GetFolder();
24
+ var intermediateFolder = Path.Combine(baseFolder, "obj");
25
+ var msiPath = Path.Combine(baseFolder, @"bin\test.msi");
26
+
27
+ var result = WixRunner.Execute(new[]
28
+ {
29
+ "build",
30
+ Path.Combine(folder, "Package.wxs"),
31
+ Path.Combine(folder, "PackageComponents.wxs"),
32
+ "-loc", Path.Combine(folder, "Package.en-us.wxl"),
33
+ "-bindpath", Path.Combine(folder, "data"),
34
+ "-intermediateFolder", intermediateFolder,
35
+ "-o", msiPath
36
+ });
37
+
38
+ result.AssertSuccess();
39
+
40
+ var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wixpdb"));
41
+ var section = intermediate.Sections.Single();
42
+
43
+ var dirSymbols = section.Symbols.OfType<WixToolset.Data.Symbols.DirectorySymbol>().ToList();
44
+ WixAssert.CompareLineByLine(new[]
45
+ {
46
+ "INSTALLFOLDER:ProgramFiles6432Folder:Example Corporation MsiPackage",
47
+ "ProgramFiles6432Folder:ProgramFilesFolder:.",
48
+ "ProgramFilesFolder:TARGETDIR:PFiles",
49
+ "TARGETDIR::SourceDir"
50
+ }, dirSymbols.OrderBy(d => d.Id.Id).Select(d => d.Id.Id + ":" + d.ParentDirectoryRef + ":" + d.Name).ToArray());
51
+ }
52
+ }
53
+
54
[Fact]
55
public void CanGet32bitProgramFiles6432Folder()
56
{
src/wix/test/WixToolsetTest.CoreIntegration/MsiFixture.cs
+1
-1
@@ -38,7 +38,7 @@ namespace WixToolsetTest.CoreIntegration
38
39
Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.msi")));
40
Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb")));
41
- Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\PFiles\MsiPackage\test.txt")));
41
+ Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\PFiles\Example Corporation MsiPackage\test.txt")));
42
43
var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wixpdb"));
44
src/wix/test/WixToolsetTest.CoreIntegration/TestData/SingleFile/Package.wxs
-8
@@ -1,17 +1,9 @@
1
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2
<Package Name="MsiPackage" Codepage="1252" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a" Compressed="no" InstallerVersion="200" Scope="perMachine">
3
-
4
-
3
<MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" />
4
5
<Feature Id="ProductFeature" Title="!(loc.FeatureTitle)">
6
<ComponentGroupRef Id="ProductComponents" />
7
</Feature>
8
</Package>
11
-
12
- <Fragment>
13
- <StandardDirectory Id="ProgramFilesFolder">
14
- <Directory Id="INSTALLFOLDER" Name="MsiPackage" SourceName="." />
15
- </StandardDirectory>
16
- </Fragment>
9
</Wix>