Add compiler extension to handle platforms.
Custom actions to print EULA and validate install directories are defined in WixUIExtension compiler extension, to handle platform-specific custom actions referred to from `DoAction` control events. This is the least-worst solution, given the `DoAction` approach used in the WixUI authoring and anyone customizing a WixUI set.
Bob Arnson committed
Jan 29, 2022 at 23:44 UTC
7ce477c6863c74ef0a50d117d8c28b2f19971b42
27 files changed
+327
-106
src/ext/UI/ca/uica.vcxproj
+16
@@ -11,6 +11,22 @@
11
<Configuration>Release</Configuration>
12
<Platform>Win32</Platform>
13
</ProjectConfiguration>
14
+ <ProjectConfiguration Include="Debug|x64">
15
+ <Configuration>Debug</Configuration>
16
+ <Platform>x64</Platform>
17
+ </ProjectConfiguration>
18
+ <ProjectConfiguration Include="Release|x64">
19
+ <Configuration>Release</Configuration>
20
+ <Platform>x64</Platform>
21
+ </ProjectConfiguration>
22
+ <ProjectConfiguration Include="Debug|ARM64">
23
+ <Configuration>Debug</Configuration>
24
+ <Platform>ARM64</Platform>
25
+ </ProjectConfiguration>
26
+ <ProjectConfiguration Include="Release|ARM64">
27
+ <Configuration>Release</Configuration>
28
+ <Platform>ARM64</Platform>
29
+ </ProjectConfiguration>
30
</ItemGroup>
31
32
<PropertyGroup Label="Globals">
src/ext/UI/test/WixToolsetTest.UI/TestData/WixUI_Advanced/Package.wxs
+3
-3
@@ -1,5 +1,5 @@
1
-<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2
- <Package Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a" InstallerVersion="200">
1
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
2
+ <Package Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
3
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
4
5
<Feature Id="ProductFeature" Title="MsiPackage">
@@ -12,7 +12,7 @@
12
</Component>
13
</ComponentGroup>
14
15
- <UIRef Id="WixUI_Advanced" />
15
+ <ui:WixUI Id="WixUI_Advanced" />
16
<Property Id="ApplicationFolderName" Value="MyProgram" />
17
<Property Id="WixAppFolder" Value="WixPerMachineFolder" />
18
</Package>
src/ext/UI/test/WixToolsetTest.UI/TestData/WixUI_FeatureTree/Package.wxs
+2
-2
@@ -1,4 +1,4 @@
1
-<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
1
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
2
<Package Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a" InstallerVersion="200">
3
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
4
@@ -12,7 +12,7 @@
12
</Component>
13
</ComponentGroup>
14
15
- <UIRef Id="WixUI_FeatureTree" />
15
+ <ui:WixUI Id="WixUI_FeatureTree" />
16
</Package>
17
18
<Fragment>
src/ext/UI/test/WixToolsetTest.UI/TestData/WixUI_InstallDir/Package.wxs
+2
-2
@@ -1,4 +1,4 @@
1
-<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
1
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
2
<Package Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a" InstallerVersion="200">
3
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
4
@@ -12,7 +12,7 @@
12
</Component>
13
</ComponentGroup>
14
15
- <UIRef Id="WixUI_InstallDir" />
15
+ <ui:WixUI Id="WixUI_InstallDir" />
16
</Package>
17
18
<Fragment>
src/ext/UI/test/WixToolsetTest.UI/TestData/WixUI_Minimal/Package.wxs
+2
-2
@@ -1,4 +1,4 @@
1
-<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
1
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
2
<Package Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a" InstallerVersion="200">
3
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
4
@@ -12,7 +12,7 @@
12
</Component>
13
</ComponentGroup>
14
15
- <UIRef Id="WixUI_Minimal" />
15
+ <ui:WixUI Id="WixUI_Minimal" />
16
</Package>
17
18
<Fragment>
src/ext/UI/test/WixToolsetTest.UI/TestData/WixUI_Mondo/Package.wxs
+2
-2
@@ -1,4 +1,4 @@
1
-<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
1
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
2
<Package Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a" InstallerVersion="200">
3
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
4
@@ -12,7 +12,7 @@
12
</Component>
13
</ComponentGroup>
14
15
- <UIRef Id="WixUI_Mondo" />
15
+ <ui:WixUI Id="WixUI_Mondo" />
16
</Package>
17
18
<Fragment>
src/ext/UI/test/WixToolsetTest.UI/UIExtensionFixture.cs
+68
-31
@@ -7,8 +7,6 @@ namespace WixToolsetTest.UI
7
using System.Linq;
8
using WixBuildTools.TestSupport;
9
using WixToolset.Core.TestPackage;
10
- using WixToolset.Data;
11
- using WixToolset.Data.Symbols;
10
using WixToolset.Data.WindowsInstaller;
11
using WixToolset.UI;
12
using Xunit;
@@ -22,11 +20,48 @@ namespace WixToolsetTest.UI
20
var bindFolder = TestData.Get(@"TestData\data");
21
var build = new Builder(folder, typeof(UIExtensionFactory), new[] { bindFolder });
22
25
- var results = build.BuildAndQuery(Build, "Property");
26
- WixAssert.CompareLineByLine(new[]
27
- {
28
- "Property:WixUI_Mode\tAdvanced",
29
- }, results.Where(s => s.StartsWith("Property:WixUI_Mode")).ToArray());
23
+ var results = build.BuildAndQuery(Build, "Dialog", "CustomAction");
24
+ Assert.Single(results, result => result.StartsWith("Dialog:AdvancedWelcomeEulaDlg\t"));
25
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixSetDefaultPerMachineFolder\t"));
26
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixSetDefaultPerUserFolder\t"));
27
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixSetPerMachineFolder\t"));
28
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixSetPerUserFolder\t"));
29
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixUIPrintEula\t65\tWixUiCa_X86\t"));
30
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixUIValidatePath\t65\tWixUiCa_X86\t"));
31
+ }
32
+
33
+ [Fact]
34
+ public void CanBuildUsingWixUIAdvancedX64()
35
+ {
36
+ var folder = TestData.Get(@"TestData\WixUI_Advanced");
37
+ var bindFolder = TestData.Get(@"TestData\data");
38
+ var build = new Builder(folder, typeof(UIExtensionFactory), new[] { bindFolder });
39
+
40
+ var results = build.BuildAndQuery(BuildX64, "Dialog", "CustomAction");
41
+ Assert.Single(results, result => result.StartsWith("Dialog:AdvancedWelcomeEulaDlg\t"));
42
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixSetDefaultPerMachineFolder\t"));
43
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixSetDefaultPerUserFolder\t"));
44
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixSetPerMachineFolder\t"));
45
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixSetPerUserFolder\t"));
46
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixUIPrintEula\t65\tWixUiCa_X64\t"));
47
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixUIValidatePath\t65\tWixUiCa_X64\t"));
48
+ }
49
+
50
+ [Fact]
51
+ public void CanBuildUsingWixUIAdvancedARM64()
52
+ {
53
+ var folder = TestData.Get(@"TestData\WixUI_Advanced");
54
+ var bindFolder = TestData.Get(@"TestData\data");
55
+ var build = new Builder(folder, typeof(UIExtensionFactory), new[] { bindFolder });
56
+
57
+ var results = build.BuildAndQuery(BuildARM64, "Dialog", "CustomAction");
58
+ Assert.Single(results, result => result.StartsWith("Dialog:AdvancedWelcomeEulaDlg\t"));
59
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixSetDefaultPerMachineFolder\t"));
60
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixSetDefaultPerUserFolder\t"));
61
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixSetPerMachineFolder\t"));
62
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixSetPerUserFolder\t"));
63
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixUIPrintEula\t65\tWixUiCa_A64\t"));
64
+ Assert.Single(results, result => result.StartsWith("CustomAction:WixUIValidatePath\t65\tWixUiCa_A64\t"));
65
}
66
67
[Fact]
@@ -36,11 +71,10 @@ namespace WixToolsetTest.UI
71
var bindFolder = TestData.Get(@"TestData\data");
72
var build = new Builder(folder, typeof(UIExtensionFactory), new[] { bindFolder });
73
39
- var results = build.BuildAndQuery(Build, "Property");
40
- WixAssert.CompareLineByLine(new[]
41
- {
42
- "Property:WixUI_Mode\tFeatureTree",
43
- }, results.Where(s => s.StartsWith("Property:WixUI_Mode")).ToArray());
74
+ var results = build.BuildAndQuery(Build, "Dialog", "CustomAction");
75
+ Assert.Single(results, result => result.StartsWith("Dialog:WelcomeDlg\t"));
76
+ Assert.Single(results, result => result.StartsWith("Dialog:CustomizeDlg\t"));
77
+ Assert.Empty(results.Where(result => result.StartsWith("Dialog:SetupTypeDlg\t")));
78
}
79
80
[Fact]
@@ -50,11 +84,8 @@ namespace WixToolsetTest.UI
84
var bindFolder = TestData.Get(@"TestData\data");
85
var build = new Builder(folder, typeof(UIExtensionFactory), new[] { bindFolder });
86
53
- var results = build.BuildAndQuery(Build, "Property");
54
- WixAssert.CompareLineByLine(new[]
55
- {
56
- "Property:WixUI_Mode\tInstallDir",
57
- }, results.Where(s => s.StartsWith("Property:WixUI_Mode")).ToArray());
87
+ var results = build.BuildAndQuery(Build, "Dialog", "CustomAction");
88
+ Assert.Single(results, result => result.StartsWith("Dialog:InstallDirDlg\t"));
89
}
90
91
[Fact]
@@ -64,11 +95,8 @@ namespace WixToolsetTest.UI
95
var bindFolder = TestData.Get(@"TestData\data");
96
var build = new Builder(folder, typeof(UIExtensionFactory), new[] { bindFolder });
97
67
- var results = build.BuildAndQuery(Build, "Property");
68
- WixAssert.CompareLineByLine(new[]
69
- {
70
- "Property:WixUI_Mode\tMinimal",
71
- }, results.Where(s => s.StartsWith("Property:WixUI_Mode")).ToArray());
98
+ var results = build.BuildAndQuery(Build, "Dialog", "CustomAction");
99
+ Assert.Single(results, result => result.StartsWith("Dialog:WelcomeEulaDlg\t"));
100
}
101
102
[Fact]
@@ -92,10 +120,8 @@ namespace WixToolsetTest.UI
120
});
121
122
var wid = WindowsInstallerData.Load(Path.Combine(intermediateFolder, @"bin\test.wixpdb"));
95
- var propertyTable = wid.Tables["Property"];
96
-
97
- var propertyRow = propertyTable.Rows.Single(r => r.GetPrimaryKey() == "WixUI_Mode");
98
- WixAssert.StringEqual("Minimal", propertyRow.FieldAsString(1));
123
+ var dialogTable = wid.Tables["Dialog"];
124
+ var dialogRow = dialogTable.Rows.Single(r => r.GetPrimaryKey() == "WelcomeEulaDlg");
125
}
126
}
127
@@ -106,11 +132,10 @@ namespace WixToolsetTest.UI
132
var bindFolder = TestData.Get(@"TestData\data");
133
var build = new Builder(folder, typeof(UIExtensionFactory), new[] { bindFolder });
134
109
- var results = build.BuildAndQuery(Build, "Property");
110
- WixAssert.CompareLineByLine(new[]
111
- {
112
- "Property:WixUI_Mode\tMondo",
113
- }, results.Where(s => s.StartsWith("Property:WixUI_Mode")).ToArray());
135
+ var results = build.BuildAndQuery(Build, "Dialog", "CustomAction");
136
+ Assert.Single(results, result => result.StartsWith("Dialog:WelcomeDlg\t"));
137
+ Assert.Single(results, result => result.StartsWith("Dialog:CustomizeDlg\t"));
138
+ Assert.Single(results, result => result.StartsWith("Dialog:SetupTypeDlg\t"));
139
}
140
141
[Fact]
@@ -133,6 +158,18 @@ namespace WixToolsetTest.UI
158
.AssertSuccess();
159
}
160
161
+ private static void BuildX64(string[] args)
162
+ {
163
+ var result = WixRunner.Execute(args.Concat(new[] { "-arch", "x64" }).ToArray())
164
+ .AssertSuccess();
165
+ }
166
+
167
+ private static void BuildARM64(string[] args)
168
+ {
169
+ var result = WixRunner.Execute(args.Concat(new[] { "-arch", "arm64" }).ToArray())
170
+ .AssertSuccess();
171
+ }
172
+
173
private static void BuildInGerman(string[] args)
174
{
175
var localizedArgs = args.Append("-culture").Append("de-DE").ToArray();
src/ext/UI/wixext/UICompiler.cs
new
+118
@@ -0,0 +1,118 @@
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.UI
4
+{
5
+ using System;
6
+ using System.Collections.Generic;
7
+ using System.Xml.Linq;
8
+ using WixToolset.Data;
9
+ using WixToolset.Data.Symbols;
10
+ using WixToolset.Extensibility;
11
+
12
+ /// <summary>
13
+ /// The decompiler for the WiX Toolset UI Extension.
14
+ /// </summary>
15
+ public sealed class UICompiler : BaseCompilerExtension
16
+ {
17
+ public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/ui";
18
+
19
+ /// <summary>
20
+ /// Processes an element for the Compiler.
21
+ /// </summary>
22
+ /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
23
+ /// <param name="parentElement">Parent element of element to process.</param>
24
+ /// <param name="element">Element to process.</param>
25
+ /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
26
+ public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
27
+ {
28
+ switch (parentElement.Name.LocalName)
29
+ {
30
+ case "Fragment":
31
+ case "Module":
32
+ case "PatchFamily":
33
+ case "Package":
34
+ case "UI":
35
+ switch (element.Name.LocalName)
36
+ {
37
+ case "WixUI":
38
+ this.ParseWixUIElement(intermediate, section, element);
39
+ break;
40
+ default:
41
+ this.ParseHelper.UnexpectedElement(parentElement, element);
42
+ break;
43
+ }
44
+ break;
45
+ default:
46
+ this.ParseHelper.UnexpectedElement(parentElement, element);
47
+ break;
48
+ }
49
+ }
50
+
51
+ /// <summary>
52
+ /// Parses a WixUI element.
53
+ /// </summary>
54
+ private void ParseWixUIElement(Intermediate intermediate, IntermediateSection section, XElement element)
55
+ {
56
+ var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
57
+ string id = null;
58
+
59
+ foreach (var attrib in element.Attributes())
60
+ {
61
+ if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
62
+ {
63
+ switch (attrib.Name.LocalName)
64
+ {
65
+ case "Id":
66
+ id = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
67
+ break;
68
+ default:
69
+ this.ParseHelper.UnexpectedAttribute(element, attrib);
70
+ break;
71
+ }
72
+ }
73
+ else
74
+ {
75
+ this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
76
+ }
77
+ }
78
+
79
+ if (null == id)
80
+ {
81
+ this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id"));
82
+ }
83
+ else
84
+ {
85
+ this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.WixUI, id);
86
+
87
+ // Because these custom actions are "scheduled" via `DoAction` control events, we have to create the
88
+ // custom action definitions here, so the `DoAction` references are static and the targets are
89
+ // dynamically created to properly reflect the platform-specific DLL and avoid having duplicate ids
90
+ // in the UI .wixlib.
91
+ var platform = this.Context.Platform == Platform.ARM64 ? "A64" : this.Context.Platform.ToString();
92
+ var source = $"WixUiCa_{platform}";
93
+
94
+ section.AddSymbol(new CustomActionSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixUIPrintEula"))
95
+ {
96
+ TargetType = CustomActionTargetType.Dll,
97
+ Target = "PrintEula",
98
+ SourceType = CustomActionSourceType.Binary,
99
+ Source = source,
100
+ IgnoreResult = true,
101
+ ExecutionType = CustomActionExecutionType.Immediate,
102
+ });
103
+
104
+ section.AddSymbol(new CustomActionSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixUIValidatePath"))
105
+ {
106
+ TargetType = CustomActionTargetType.Dll,
107
+ Target = "ValidatePath",
108
+ SourceType = CustomActionSourceType.Binary,
109
+ Source = source,
110
+ IgnoreResult = true,
111
+ ExecutionType = CustomActionExecutionType.Immediate,
112
+ });
113
+ }
114
+
115
+ this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
116
+ }
117
+ }
118
+}
src/ext/UI/wixext/UIExtensionFactory.cs
+1
@@ -11,6 +11,7 @@ namespace WixToolset.UI
11
protected override IReadOnlyCollection<Type> ExtensionTypes => new[]
12
{
13
typeof(UIExtensionData),
14
+ typeof(UICompiler),
15
};
16
}
17
}
src/ext/UI/wixlib/Common_Platform.wxi
+7
-10
@@ -2,18 +2,15 @@
2
3
4
<Include xmlns="http://wixtoolset.org/schemas/v4/wxs">
5
- <?include caSuffix.wxi ?>
6
- <Fragment>
7
- <!-- print EULA functionality -->
8
- <CustomAction Id="WixUIPrintEula$(var.Suffix)" DllEntry="PrintEula" Return="ignore" Execute="immediate" BinaryRef="WixUIWixca$(var.Suffix)" />
9
- </Fragment>
5
+ <?include ..\..\caDecor.wxi ?>
6
11
- <Fragment>
12
- <!-- Validate install directory -->
13
- <CustomAction Id="WixUIValidatePath$(var.Suffix)" DllEntry="ValidatePath" Return="ignore" Execute="immediate" BinaryRef="WixUIWixca$(var.Suffix)" />
14
- </Fragment>
7
+ <!--
8
+ Custom actions to print EULA amd validate install directories are defined
9
+ in WixUIExtension compiler extension, to handle platform-specific custom
10
+ actions referred to from `DoAction` control events.
11
+ -->
12
13
<Fragment>
17
- <Binary Id="WixUIWixca$(var.Suffix)" SourceFile="!(bindpath.$(var.platform))uica.dll" />
14
+ <Binary Id="WixUiCa$(var.Suffix)" SourceFile="!(bindpath.$(var.platform))uica.dll" />
15
</Fragment>
16
</Include>
src/ext/UI/wixlib/Common_arm64.wxs
new
+7
@@ -0,0 +1,7 @@
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
+
4
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5
+ <?define platform=arm64 ?>
6
+ <?include Common_Platform.wxi ?>
7
+</Wix>
src/ext/UI/wixlib/Common_x64.wxs
new
+7
@@ -0,0 +1,7 @@
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
+
4
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5
+ <?define platform=x64 ?>
6
+ <?include Common_Platform.wxi ?>
7
+</Wix>
src/ext/UI/wixlib/WixUI_Advanced.wxs
-1
@@ -53,7 +53,6 @@ Todo:
53
<TextStyle Id="WixUI_Font_Emphasized" FaceName="!(loc.Advanced_Font_FaceName)" Size="!(loc.Advanced_Font_Emphasized_Size)" Bold="yes" />
54
55
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
56
- <Property Id="WixUI_Mode" Value="Advanced" />
56
57
<DialogRef Id="BrowseDlg" />
58
<DialogRef Id="DiskCostDlg" />
src/ext/UI/wixlib/WixUI_FeatureTree.wxs
-1
@@ -29,7 +29,6 @@ Patch dialog sequence:
29
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
30
31
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
32
- <Property Id="WixUI_Mode" Value="FeatureTree" />
32
33
<DialogRef Id="ErrorDlg" />
34
<DialogRef Id="FatalError" />
src/ext/UI/wixlib/WixUI_InstallDir.wxs
-1
@@ -30,7 +30,6 @@ Patch dialog sequence:
30
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
31
32
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
33
- <Property Id="WixUI_Mode" Value="InstallDir" />
33
34
<DialogRef Id="BrowseDlg" />
35
<DialogRef Id="DiskCostDlg" />
src/ext/UI/wixlib/WixUI_Minimal.wxs
-1
@@ -24,7 +24,6 @@ Patch dialog sequence:
24
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
25
26
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
27
- <Property Id="WixUI_Mode" Value="Minimal" />
27
28
<DialogRef Id="ErrorDlg" />
29
<DialogRef Id="FatalError" />
src/ext/UI/wixlib/WixUI_Mondo.wxs
-1
@@ -31,7 +31,6 @@ Patch dialog sequence:
31
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
32
33
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
34
- <Property Id="WixUI_Mode" Value="Mondo" />
34
35
<DialogRef Id="ErrorDlg" />
36
<DialogRef Id="FatalError" />
src/ext/UI/wixlib/caSuffix.wxi
deleted
-27
@@ -1,27 +0,0 @@
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
-<Include xmlns="http://wixtoolset.org/schemas/v4/wxs">
4
- <?ifndef platform ?>
5
- <?error Required value "platform" not defined in include caSuffix.wxi ?>
6
- <?endif?>
7
-
8
- <?ifdef Suffix ?>
9
- <?undef Suffix ?>
10
- <?undef DeferredSuffix ?>
11
- <?endif?>
12
-
13
- <?if $(var.platform)="x86" ?>
14
- <?define Suffix="" ?>
15
- <?define DeferredSuffix="" ?>
16
- <?endif?>
17
-
18
- <?if $(var.platform)="x64" ?>
19
- <?define Suffix="_x64" ?>
20
- <?define DeferredSuffix="_64" ?>
21
- <?endif?>
22
-
23
- <?if $(var.platform)="arm" ?>
24
- <?define Suffix="_ARM" ?>
25
- <?define DeferredSuffix="_ARM" ?>
26
- <?endif?>
27
-</Include>
src/ext/UI/wixlib/ui.wixproj
+3
-1
@@ -27,7 +27,9 @@
27
</ItemGroup>
28
29
<ItemGroup>
30
- <ProjectReference Include="..\ca\uica.vcxproj" Properties="Platform=x86" ReferenceOutputAssembly="false" />
30
+ <ProjectReference Include="..\ca\uica.vcxproj" Properties="Platform=x86" />
31
+ <ProjectReference Include="..\ca\uica.vcxproj" Properties="Platform=x64" />
32
+ <ProjectReference Include="..\ca\uica.vcxproj" Properties="Platform=ARM64" />
33
</ItemGroup>
34
35
<ItemGroup>
src/test/burn/TestData/FilesInUseTests/PackageA/PackageA.wxs
+2
-2
@@ -1,10 +1,10 @@
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
-<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
4
<Fragment>
5
<ComponentGroup Id="ProductComponents" />
6
7
- <UIRef Id="WixUI_Minimal" />
7
+ <ui:WixUI Id="WixUI_Minimal" />
8
<WixVariable Id="WixUILicenseRtf" Value="license.txt" />
9
</Fragment>
10
</Wix>
src/test/wix/TestData/WixprojLibraryVcxprojDll/Library.wxs
+1
-3
@@ -1,11 +1,9 @@
1
-<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
1
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
2
<Fragment>
3
<ComponentGroup Id='VcxprojDllComponentGroup' Directory='ApplicationFolder'>
4
<Component>
5
<File Source='VcxprojDll.dll' />
6
</Component>
7
</ComponentGroup>
8
-
9
- <UIRef Id="WixUI_Minimal" />
8
</Fragment>
9
</Wix>
src/test/wix/TestData/WixprojPackageCsprojWebApplicationNetCore/Package.wxs
-2
@@ -12,7 +12,5 @@
12
<File Source='web.config' />
13
</Component>
14
</Feature>
15
-
16
- <UIRef Id="WixUI_Minimal" />
15
</Package>
16
</Wix>
src/test/wix/TestData/WixprojPackageCsprojWebApplicationNetCore/WixprojPackageCsprojWebApplicationNetCore.wixproj
-1
@@ -11,7 +11,6 @@
11
<ItemGroup>
12
<!-- SkipPublish="true" BindPath="$(MSBuildProjectDirectory)\does\not\exist" BindName="Xxx" Publish="true" -->
13
<ProjectReference Include="..\CsprojWebApplicationNetCore\CsprojWebApplicationNetCore.csproj" Publish="true" />
14
- <PackageReference Include="WixToolset.UI.wixext" Version="4.0.0-preview.0" />
14
</ItemGroup>
15
16
<!-- <Import Sdk="WixToolset.Sdk" Project='D:\src\wix4\build\wix\Debug\netcoreapp3.1\Sdk\Sdk.targets' /> -->
src/test/wix/TestData/WixprojPackageVcxprojWindowsApp/Package.wxs
-2
@@ -16,7 +16,5 @@
16
17
<MergeRef Id='WinFormsModule' />
18
</Feature>
19
-
20
- <UIRef Id="WixUI_Minimal" />
19
</Package>
20
</Wix>
src/test/wix/TestData/WixprojPackageVcxprojWindowsApp/WixprojPackageVcxprojWindowsApp.wixproj
-2
@@ -5,7 +5,5 @@
5
<ProjectReference Include="..\VcxprojWindowsApp\VcxprojWindowsApp.vcxproj" />
6
<ProjectReference Include="..\WixprojLibraryVcxprojDll\WixprojLibraryVcxprojDll.wixproj" />
7
<ProjectReference Include="..\WixprojModuleCsprojWinFormsNetFx\WixprojModuleCsprojWinFormsNetFx.wixproj" />
8
-
9
- <PackageReference Include="WixToolset.UI.wixext" Version="4.0.0-preview.0" />
8
</ItemGroup>
9
</Project>
src/wix/WixToolset.Converters/WixConverter.cs
+27
-9
@@ -57,6 +57,7 @@ namespace WixToolset.Converters
57
private static readonly XNamespace WixBalNamespace = "http://wixtoolset.org/schemas/v4/wxs/bal";
58
private static readonly XNamespace WixDependencyNamespace = "http://wixtoolset.org/schemas/v4/wxs/dependency";
59
private static readonly XNamespace WixFirewallNamespace = "http://wixtoolset.org/schemas/v4/wxs/firewall";
60
+ private static readonly XNamespace WixUiNamespace = "http://wixtoolset.org/schemas/v4/wxs/ui";
61
private static readonly XNamespace WixUtilNamespace = "http://wixtoolset.org/schemas/v4/wxs/util";
62
private static readonly XNamespace WixVSNamespace = "http://wixtoolset.org/schemas/v4/wxs/vs";
63
@@ -142,6 +143,7 @@ namespace WixToolset.Converters
143
private static readonly XName UtilXmlConfigElementName = WixUtilNamespace + "XmlConfig";
144
private static readonly XName CustomActionElementName = WixNamespace + "CustomAction";
145
private static readonly XName CustomActionRefElementName = WixNamespace + "CustomActionRef";
146
+ private static readonly XName UIRefElementName = WixNamespace + "UIRef";
147
private static readonly XName PropertyElementName = WixNamespace + "Property";
148
private static readonly XName Wix4ElementName = WixNamespace + "Wix";
149
private static readonly XName Wix3ElementName = Wix3Namespace + "Wix";
@@ -259,6 +261,7 @@ namespace WixToolset.Converters
261
{ WixConverter.WixElementWithoutNamespaceName, this.ConvertElementWithoutNamespace },
262
{ WixConverter.IncludeElementWithoutNamespaceName, this.ConvertElementWithoutNamespace },
263
{ WixConverter.VerbElementName, this.ConvertVerbElement },
264
+ { WixConverter.UIRefElementName, this.ConvertUIRefElement },
265
};
266
267
this.Messaging = messaging;
@@ -1275,14 +1278,14 @@ namespace WixToolset.Converters
1278
xPackage.SetAttributeValue("Scope", "perUser");
1279
break;
1280
case "elevated":
1281
+ {
1282
+ var xAllUsers = xPackage.Elements(PropertyElementName).SingleOrDefault(p => p.Attribute("Id")?.Value == "ALLUSERS");
1283
+ if (xAllUsers?.Attribute("Value")?.Value == "1")
1284
{
1279
- var xAllUsers = xPackage.Elements(PropertyElementName).SingleOrDefault(p => p.Attribute("Id")?.Value == "ALLUSERS");
1280
- if (xAllUsers?.Attribute("Value")?.Value == "1")
1281
- {
1282
- xAllUsers?.Remove();
1283
- }
1285
+ xAllUsers?.Remove();
1286
}
1285
- break;
1287
+ }
1288
+ break;
1289
}
1290
1291
xInstallPrivileges?.Remove();
@@ -1439,7 +1442,7 @@ namespace WixToolset.Converters
1442
}
1443
1444
if (!String.IsNullOrEmpty(newElementName)
1442
- && this.OnError(ConverterTestType.ReferencesReplaced, element, "Custom action and property reference {0} have been replaced with strongly-typed elements.", id))
1445
+ && this.OnError(ConverterTestType.ReferencesReplaced, element, "UI, custom action, and property reference {0} has been replaced with strongly-typed element.", id))
1446
{
1447
this.XRoot.SetAttributeValue(XNamespace.Xmlns + newNamespaceName, newNamespace.NamespaceName);
1448
@@ -1452,6 +1455,21 @@ namespace WixToolset.Converters
1455
}
1456
}
1457
1458
+ private void ConvertUIRefElement(XElement element)
1459
+ {
1460
+ var id = element.Attribute("Id")?.Value;
1461
+
1462
+ if (id?.StartsWith("WixUI_") == true
1463
+ && this.OnError(ConverterTestType.ReferencesReplaced, element, "UI, custom action, and property reference {0} has been replaced with strongly-typed element.", id))
1464
+ {
1465
+ this.XRoot.SetAttributeValue(XNamespace.Xmlns + "ui", WixUiNamespace.NamespaceName);
1466
+
1467
+ element.AddBeforeSelf(new XElement(WixUiNamespace + "WixUI", new XAttribute("Id", id)));
1468
+
1469
+ element.Remove();
1470
+ }
1471
+ }
1472
+
1473
private void ConvertCustomActionRefElement(XElement element)
1474
{
1475
var newElementName = String.Empty;
@@ -1471,7 +1489,7 @@ namespace WixToolset.Converters
1489
}
1490
1491
if (!String.IsNullOrEmpty(newElementName)
1474
- && this.OnError(ConverterTestType.ReferencesReplaced, element, "Custom action and property reference {0} have been replaced with strongly-typed elements.", id))
1492
+ && this.OnError(ConverterTestType.ReferencesReplaced, element, "UI, custom action, and property reference {0} has been replaced with strongly-typed element.", id))
1493
{
1494
element.AddAfterSelf(new XElement(WixUtilNamespace + newElementName));
1495
element.Remove();
@@ -2532,7 +2550,7 @@ namespace WixToolset.Converters
2550
DefiningStandardDirectoryDeprecated,
2551
2552
/// <summary>
2535
- /// Naked custom action and property references replaced with elements.
2553
+ /// Naked UI, custom action, and property references replaced with elements.
2554
/// </summary>
2555
ReferencesReplaced,
2556
src/wix/test/WixToolsetTest.Converters/UIExtensionFixture.cs
new
+59
@@ -0,0 +1,59 @@
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 WixToolsetTest.Converters
4
+{
5
+ using System;
6
+ using System.Xml.Linq;
7
+ using WixBuildTools.TestSupport;
8
+ using WixToolset.Converters;
9
+ using WixToolsetTest.Converters.Mocks;
10
+ using Xunit;
11
+
12
+ public class UIExtensionFixture : BaseConverterFixture
13
+ {
14
+ [Fact]
15
+ public void FixUIRefs()
16
+ {
17
+ var parse = String.Join(Environment.NewLine,
18
+ "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>",
19
+ " <Fragment>",
20
+ " <UIRef Id=\"WixUI_Advanced\" />",
21
+ " <UIRef Id=\"WixUI_FeatureTree\" />",
22
+ " <UIRef Id=\"WixUI_BobsSpecialUI\" />",
23
+ " <UI>",
24
+ " <UIRef Id=\"WixUI_Advanced\" />",
25
+ " <UIRef Id=\"WixUI_FeatureTree\" />",
26
+ " <UIRef Id=\"WixUI_BobsSpecialUI\" />",
27
+ " </UI>",
28
+ " </Fragment>",
29
+ "</Wix>");
30
+
31
+ var expected = new[]
32
+ {
33
+ "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\" xmlns:ui=\"http://wixtoolset.org/schemas/v4/wxs/ui\">",
34
+ " <Fragment>",
35
+ " <ui:WixUI Id=\"WixUI_Advanced\" />",
36
+ " <ui:WixUI Id=\"WixUI_FeatureTree\" />",
37
+ " <ui:WixUI Id=\"WixUI_BobsSpecialUI\" />",
38
+ " <UI>",
39
+ " <ui:WixUI Id=\"WixUI_Advanced\" />",
40
+ " <ui:WixUI Id=\"WixUI_FeatureTree\" />",
41
+ " <ui:WixUI Id=\"WixUI_BobsSpecialUI\" />",
42
+ " </UI>",
43
+ " </Fragment>",
44
+ "</Wix>"
45
+ };
46
+
47
+ var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
48
+
49
+ var messaging = new MockMessaging();
50
+ var converter = new WixConverter(messaging, 2, null, null);
51
+
52
+ var errors = converter.ConvertDocument(document);
53
+ Assert.Equal(7, errors);
54
+
55
+ var actualLines = UnformattedDocumentLines(document);
56
+ WixAssert.CompareLineByLine(expected, actualLines);
57
+ }
58
+ }
59
+}