main
cs 176 lines 6.7 KB
Raw
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.Data
4 {
5 using System;
6 using System.Collections.Generic;
7 using System.Linq;
8 using WixToolset.Data.Bind;
9 using WixToolset.Data.Symbols;
10 using WixToolset.Data.WindowsInstaller;
11
12 /// <summary>
13 /// WiX Standard Library implementation.
14 /// </summary>
15 public static class WixStandardLibrary
16 {
17 private const string WixStandardLibraryId = "wixstd";
18
19 /// <summary>
20 /// Build the wixstd.wixlib Intermediate.
21 /// </summary>
22 /// <param name="platform">Target platform for the wixstd.wixlib</param>
23 /// <returns>Intermediate containing the wixstd.wixlib.</returns>
24 public static Intermediate Build(Platform platform)
25 {
26 var localizations = YieldLocalizations();
27
28 var sections = YieldSections(platform);
29
30 return new Intermediate(WixStandardLibraryId, IntermediateLevels.Combined, sections, localizations.ToDictionary(l => l.Culture, StringComparer.OrdinalIgnoreCase));
31 }
32
33 private static IEnumerable<Localization> YieldLocalizations()
34 {
35 var sourceLineNumber = new SourceLineNumber("wixstd.wixlib");
36
37 var strings = new[] {
38 new BindVariable()
39 {
40 SourceLineNumbers = sourceLineNumber,
41 Id = "WixDowngradePreventedMessage",
42 Value = "A newer version of [ProductName] is already installed.",
43 Overridable = true,
44 },
45 };
46
47 var localizedControls = new LocalizedControl[0];
48
49 yield return new Localization(LocalizationLocation.Library, null, null, String.Empty, strings.ToDictionary(s => s.Id), localizedControls.ToDictionary(l => l.GetKey()));
50 }
51
52 private static IEnumerable<IntermediateSection> YieldSections(Platform platform)
53 {
54 var sourceLineNumber = new SourceLineNumber("wixstd.wixlib");
55
56 // Actions.
57 foreach (var actionSymbol in WindowsInstallerStandard.StandardActions())
58 {
59 var symbol = new WixActionSymbol(sourceLineNumber, new Identifier(actionSymbol.Id.Access, actionSymbol.Id.Id))
60 {
61 Action = actionSymbol.Action,
62 SequenceTable = actionSymbol.SequenceTable,
63 Sequence = actionSymbol.Sequence,
64 Condition = actionSymbol.Condition,
65 };
66
67 var section = CreateSectionAroundSymbol(symbol);
68
69 yield return section;
70 }
71
72 // Directories.
73 foreach (var id in WindowsInstallerStandard.StandardDirectoryIds())
74 {
75 var symbol = new DirectorySymbol(sourceLineNumber, new Identifier(AccessModifier.Virtual, id))
76 {
77 ParentDirectoryRef = GetStandardDirectoryParent(id, platform),
78 Name = WindowsInstallerStandard.TryGetStandardDirectoryName(id, out var name) ? name : throw new InvalidOperationException("Standard directories must have a default name")
79 };
80
81 var section = CreateSectionAroundSymbol(symbol);
82
83 // Add a reference for the more complicated parent directory references.
84 if (symbol.ParentDirectoryRef != null && symbol.ParentDirectoryRef != "TARGEDIR")
85 {
86 section.AddSymbol(new WixSimpleReferenceSymbol(sourceLineNumber)
87 {
88 Table = "Directory",
89 PrimaryKeys = symbol.ParentDirectoryRef
90 });
91 }
92
93 yield return section;
94 }
95
96 // Default feature.
97 {
98 var symbol = new FeatureSymbol(sourceLineNumber, new Identifier(AccessModifier.Virtual, WixStandardLibraryIdentifiers.DefaultFeatureName))
99 {
100 Level = 1,
101 Display = 0,
102 InstallDefault = FeatureInstallDefault.Local,
103 };
104
105 var section = CreateSectionAroundSymbol(symbol);
106
107 yield return section;
108 }
109
110 // Package References.
111 {
112 var section = CreateSection(WixStandardLibraryIdentifiers.WixStandardPackageReferences);
113
114 section.AddSymbol(new WixFragmentSymbol(sourceLineNumber, new Identifier(AccessModifier.Global, WixStandardLibraryIdentifiers.WixStandardPackageReferences)));
115
116 section.AddSymbol(new WixSimpleReferenceSymbol(sourceLineNumber)
117 {
118 Table = SymbolDefinitions.Directory.Name,
119 PrimaryKeys = "TARGETDIR"
120 });
121
122 yield return section;
123 }
124
125 // Module References.
126 {
127 var section = CreateSection(WixStandardLibraryIdentifiers.WixStandardModuleReferences);
128
129 section.AddSymbol(new WixFragmentSymbol(sourceLineNumber, new Identifier(AccessModifier.Global, WixStandardLibraryIdentifiers.WixStandardModuleReferences)));
130
131 section.AddSymbol(new WixSimpleReferenceSymbol(sourceLineNumber)
132 {
133 Table = SymbolDefinitions.Directory.Name,
134 PrimaryKeys = "TARGETDIR"
135 });
136
137 yield return section;
138 }
139 }
140
141 private static IntermediateSection CreateSection(string sectionId)
142 {
143 return new IntermediateSection(sectionId, SectionType.Fragment, WixStandardLibraryId).AssignToLibrary(WixStandardLibraryId);
144 }
145
146 private static IntermediateSection CreateSectionAroundSymbol(IntermediateSymbol symbol)
147 {
148 var section = CreateSection(symbol.Id.Id);
149
150 section.AddSymbol(symbol);
151
152 return section;
153 }
154
155 private static string GetStandardDirectoryParent(string directoryId, Platform platform)
156 {
157 switch (directoryId)
158 {
159 case "TARGETDIR":
160 return null;
161
162 case "CommonFiles6432Folder":
163 return platform == Platform.X86 ? "CommonFilesFolder" : "CommonFiles64Folder";
164
165 case "ProgramFiles6432Folder":
166 return platform == Platform.X86 ? "ProgramFilesFolder" : "ProgramFiles64Folder";
167
168 case "System6432Folder":
169 return platform == Platform.X86 ? "SystemFolder" : "System64Folder";
170
171 default:
172 return "TARGETDIR";
173 }
174 }
175 }
176 }