Integrate latest changes to tuple definitions
Rob Mensching committed
May 22, 2019 at 00:54 UTC
b645ddc2c1386c1199ca1e7790201d7a5ab6627b
2 files changed
+1020
-655
src/WixToolset.Converters.Tupleizer/ConvertTuplesCommand.cs
+565
-363
@@ -3,6 +3,7 @@
3
namespace WixToolset.Converters.Tupleizer
4
{
5
using System;
6
+ using System.Collections.Generic;
7
using System.Linq;
8
using WixToolset.Data;
9
using WixToolset.Data.Tuples;
@@ -21,11 +22,17 @@ namespace WixToolset.Converters.Tupleizer
22
{
23
var section = new IntermediateSection(String.Empty, OutputType3ToSectionType4(output.Type), output.Codepage);
24
25
+ var wixMediaByDiskId = IndexWixMediaTableByDiskId(output);
26
+ var bindPathsById = IndexById<Wix3.Row>(output, "BindPath");
27
+ var fontsById = IndexById<Wix3.Row>(output, "Font");
28
+ var selfRegById = IndexById<Wix3.Row>(output, "SelfReg");
29
+ var wixDirectoryById = IndexById<Wix3.Row>(output, "WixDirectory");
30
+
31
foreach (Wix3.Table table in output.Tables)
32
{
33
foreach (Wix3.Row row in table.Rows)
34
{
28
- var tuple = GenerateTupleFromRow(row);
35
+ var tuple = GenerateTupleFromRow(row, wixMediaByDiskId, fontsById, bindPathsById, selfRegById, wixDirectoryById);
36
if (tuple != null)
37
{
38
section.Tuples.Add(tuple);
@@ -36,353 +43,534 @@ namespace WixToolset.Converters.Tupleizer
43
return new Intermediate(String.Empty, new[] { section }, localizationsByCulture: null, embedFilePaths: null);
44
}
45
39
- private static IntermediateTuple GenerateTupleFromRow(Wix3.Row row)
46
+ private static Dictionary<int, Wix3.WixMediaRow> IndexWixMediaTableByDiskId(Wix3.Output output)
47
+ {
48
+ var wixMediaByDiskId = new Dictionary<int, Wix3.WixMediaRow>();
49
+ var wixMediaTable = output.Tables["WixMedia"];
50
+
51
+ if (wixMediaTable != null)
52
+ {
53
+ foreach (Wix3.WixMediaRow row in wixMediaTable.Rows)
54
+ {
55
+ wixMediaByDiskId.Add(FieldAsInt(row, 0), row);
56
+ }
57
+ }
58
+
59
+ return wixMediaByDiskId;
60
+ }
61
+
62
+ private static Dictionary<string, T> IndexById<T>(Wix3.Output output, string tableName) where T : Wix3.Row
63
+ {
64
+ var byId = new Dictionary<string, T>();
65
+ var table = output.Tables[tableName];
66
+
67
+ if (table != null)
68
+ {
69
+ foreach (T row in table.Rows)
70
+ {
71
+ byId.Add(FieldAsString(row, 0), row);
72
+ }
73
+ }
74
+
75
+ return byId;
76
+ }
77
+
78
+ private static IntermediateTuple GenerateTupleFromRow(Wix3.Row row, Dictionary<int, Wix3.WixMediaRow> wixMediaByDiskId, Dictionary<string, Wix3.Row> fontsById, Dictionary<string, Wix3.Row> bindPathsById, Dictionary<string, Wix3.Row> selfRegById, Dictionary<string, Wix3.Row> wixDirectoryById)
79
{
80
var name = row.Table.Name;
81
switch (name)
82
{
44
- case "_SummaryInformation":
45
- return DefaultTupleFromRow(typeof(_SummaryInformationTuple), row, columnZeroIsId: false);
46
- case "ActionText":
47
- return DefaultTupleFromRow(typeof(ActionTextTuple), row, columnZeroIsId: false);
48
- case "AdvtExecuteSequence":
49
- return DefaultTupleFromRow(typeof(AdvtExecuteSequenceTuple), row, columnZeroIsId: false);
50
- case "AppId":
51
- return DefaultTupleFromRow(typeof(AppIdTuple), row, columnZeroIsId: false);
52
- case "AppSearch":
53
- return DefaultTupleFromRow(typeof(AppSearchTuple), row, columnZeroIsId: false);
54
- case "Binary":
55
- return DefaultTupleFromRow(typeof(BinaryTuple), row, columnZeroIsId: false);
56
- case "Class":
57
- return DefaultTupleFromRow(typeof(ClassTuple), row, columnZeroIsId: false);
58
- case "CompLocator":
59
- return DefaultTupleFromRow(typeof(CompLocatorTuple), row, columnZeroIsId: true);
60
- case "Component":
61
- {
62
- var attributes = FieldAsNullableInt(row, 3);
63
-
64
- var location = ComponentLocation.LocalOnly;
65
- if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesSourceOnly) == WindowsInstallerConstants.MsidbComponentAttributesSourceOnly)
66
- {
67
- location = ComponentLocation.SourceOnly;
68
- }
69
- else if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesOptional) == WindowsInstallerConstants.MsidbComponentAttributesOptional)
70
- {
71
- location = ComponentLocation.Either;
72
- }
83
+ case "_SummaryInformation":
84
+ return DefaultTupleFromRow(typeof(SummaryInformationTuple), row, columnZeroIsId: false);
85
+ case "ActionText":
86
+ return DefaultTupleFromRow(typeof(ActionTextTuple), row, columnZeroIsId: false);
87
+ case "AdvtExecuteSequence":
88
+ return DefaultTupleFromRow(typeof(AdvtExecuteSequenceTuple), row, columnZeroIsId: false);
89
+ case "AppId":
90
+ return DefaultTupleFromRow(typeof(AppIdTuple), row, columnZeroIsId: false);
91
+ case "AppSearch":
92
+ return DefaultTupleFromRow(typeof(AppSearchTuple), row, columnZeroIsId: false);
93
+ case "Billboard":
94
+ return DefaultTupleFromRow(typeof(BillboardTuple), row, columnZeroIsId: true);
95
+ case "Binary":
96
+ return DefaultTupleFromRow(typeof(BinaryTuple), row, columnZeroIsId: true);
97
+ case "BindPath":
98
+ return null;
99
+ case "CCPSearch":
100
+ return DefaultTupleFromRow(typeof(CCPSearchTuple), row, columnZeroIsId: true);
101
+ case "Class":
102
+ return DefaultTupleFromRow(typeof(ClassTuple), row, columnZeroIsId: false);
103
+ case "CompLocator":
104
+ return DefaultTupleFromRow(typeof(CompLocatorTuple), row, columnZeroIsId: true);
105
+ case "Component":
106
+ {
107
+ var attributes = FieldAsNullableInt(row, 3);
108
74
- var keyPathType = ComponentKeyPathType.File;
75
- if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath) == WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath)
76
- {
77
- keyPathType = ComponentKeyPathType.Registry;
78
- }
79
- else if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource) == WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource)
80
- {
81
- keyPathType = ComponentKeyPathType.OdbcDataSource;
82
- }
109
+ var location = ComponentLocation.LocalOnly;
110
+ if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesSourceOnly) == WindowsInstallerConstants.MsidbComponentAttributesSourceOnly)
111
+ {
112
+ location = ComponentLocation.SourceOnly;
113
+ }
114
+ else if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesOptional) == WindowsInstallerConstants.MsidbComponentAttributesOptional)
115
+ {
116
+ location = ComponentLocation.Either;
117
+ }
118
84
- return new ComponentTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
85
- {
86
- ComponentId = FieldAsString(row, 1),
87
- Directory_ = FieldAsString(row, 2),
88
- Condition = FieldAsString(row, 4),
89
- KeyPath = FieldAsString(row, 5),
90
- Location = location,
91
- DisableRegistryReflection = (attributes & WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection) == WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection,
92
- NeverOverwrite = (attributes & WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite) == WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite,
93
- Permanent = (attributes & WindowsInstallerConstants.MsidbComponentAttributesPermanent) == WindowsInstallerConstants.MsidbComponentAttributesPermanent,
94
- SharedDllRefCount = (attributes & WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount) == WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount,
95
- Shared = (attributes & WindowsInstallerConstants.MsidbComponentAttributesShared) == WindowsInstallerConstants.MsidbComponentAttributesShared,
96
- Transitive = (attributes & WindowsInstallerConstants.MsidbComponentAttributesTransitive) == WindowsInstallerConstants.MsidbComponentAttributesTransitive,
97
- UninstallWhenSuperseded = (attributes & WindowsInstallerConstants.MsidbComponentAttributesUninstallOnSupersedence) == WindowsInstallerConstants.MsidbComponentAttributesUninstallOnSupersedence,
98
- Win64 = (attributes & WindowsInstallerConstants.MsidbComponentAttributes64bit) == WindowsInstallerConstants.MsidbComponentAttributes64bit,
99
- KeyPathType = keyPathType,
100
- };
119
+ var keyPathType = ComponentKeyPathType.File;
120
+ if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath) == WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath)
121
+ {
122
+ keyPathType = ComponentKeyPathType.Registry;
123
+ }
124
+ else if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource) == WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource)
125
+ {
126
+ keyPathType = ComponentKeyPathType.OdbcDataSource;
127
}
128
103
- case "Condition":
104
- return DefaultTupleFromRow(typeof(ConditionTuple), row, columnZeroIsId: false);
105
- case "CreateFolder":
106
- return DefaultTupleFromRow(typeof(CreateFolderTuple), row, columnZeroIsId: false);
107
- case "CustomAction":
129
+ return new ComponentTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
130
{
109
- var caType = FieldAsInt(row, 1);
110
- var executionType = DetermineCustomActionExecutionType(caType);
111
- var sourceType = DetermineCustomActionSourceType(caType);
112
- var targetType = DetermineCustomActionTargetType(caType);
131
+ ComponentId = FieldAsString(row, 1),
132
+ DirectoryRef = FieldAsString(row, 2),
133
+ Condition = FieldAsString(row, 4),
134
+ KeyPath = FieldAsString(row, 5),
135
+ Location = location,
136
+ DisableRegistryReflection = (attributes & WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection) == WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection,
137
+ NeverOverwrite = (attributes & WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite) == WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite,
138
+ Permanent = (attributes & WindowsInstallerConstants.MsidbComponentAttributesPermanent) == WindowsInstallerConstants.MsidbComponentAttributesPermanent,
139
+ SharedDllRefCount = (attributes & WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount) == WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount,
140
+ Shared = (attributes & WindowsInstallerConstants.MsidbComponentAttributesShared) == WindowsInstallerConstants.MsidbComponentAttributesShared,
141
+ Transitive = (attributes & WindowsInstallerConstants.MsidbComponentAttributesTransitive) == WindowsInstallerConstants.MsidbComponentAttributesTransitive,
142
+ UninstallWhenSuperseded = (attributes & WindowsInstallerConstants.MsidbComponentAttributesUninstallOnSupersedence) == WindowsInstallerConstants.MsidbComponentAttributesUninstallOnSupersedence,
143
+ Win64 = (attributes & WindowsInstallerConstants.MsidbComponentAttributes64bit) == WindowsInstallerConstants.MsidbComponentAttributes64bit,
144
+ KeyPathType = keyPathType,
145
+ };
146
+ }
147
114
- return new CustomActionTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
115
- {
116
- ExecutionType = executionType,
117
- SourceType = sourceType,
118
- Source = FieldAsString(row, 2),
119
- TargetType = targetType,
120
- Target = FieldAsString(row, 3),
121
- Win64 = (caType & WindowsInstallerConstants.MsidbCustomActionType64BitScript) == WindowsInstallerConstants.MsidbCustomActionType64BitScript,
122
- TSAware = (caType & WindowsInstallerConstants.MsidbCustomActionTypeTSAware) == WindowsInstallerConstants.MsidbCustomActionTypeTSAware,
123
- Impersonate = (caType & WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate) != WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate,
124
- IgnoreResult = (caType & WindowsInstallerConstants.MsidbCustomActionTypeContinue) == WindowsInstallerConstants.MsidbCustomActionTypeContinue,
125
- Hidden = (caType & WindowsInstallerConstants.MsidbCustomActionTypeHideTarget) == WindowsInstallerConstants.MsidbCustomActionTypeHideTarget,
126
- Async = (caType & WindowsInstallerConstants.MsidbCustomActionTypeAsync) == WindowsInstallerConstants.MsidbCustomActionTypeAsync,
127
- };
128
- }
148
+ case "Condition":
149
+ return DefaultTupleFromRow(typeof(ConditionTuple), row, columnZeroIsId: false);
150
+ case "CreateFolder":
151
+ return DefaultTupleFromRow(typeof(CreateFolderTuple), row, columnZeroIsId: false);
152
+ case "CustomAction":
153
+ {
154
+ var caType = FieldAsInt(row, 1);
155
+ var executionType = DetermineCustomActionExecutionType(caType);
156
+ var sourceType = DetermineCustomActionSourceType(caType);
157
+ var targetType = DetermineCustomActionTargetType(caType);
158
130
- case "Directory":
131
- return DefaultTupleFromRow(typeof(DirectoryTuple), row, columnZeroIsId: false);
132
- case "DrLocator":
133
- return DefaultTupleFromRow(typeof(DrLocatorTuple), row, columnZeroIsId: false);
134
- case "Error":
135
- return DefaultTupleFromRow(typeof(ErrorTuple), row, columnZeroIsId: false);
136
- case "Extension":
137
- return DefaultTupleFromRow(typeof(ExtensionTuple), row, columnZeroIsId: false);
138
- case "Feature":
139
- {
140
- int attributes = FieldAsInt(row, 7);
141
- var installDefault = FeatureInstallDefault.Local;
142
- if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFollowParent) == WindowsInstallerConstants.MsidbFeatureAttributesFollowParent)
143
- {
144
- installDefault = FeatureInstallDefault.FollowParent;
145
- }
146
- else
147
- if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorSource) == WindowsInstallerConstants.MsidbFeatureAttributesFavorSource)
148
- {
149
- installDefault = FeatureInstallDefault.Source;
150
- }
159
+ return new CustomActionTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
160
+ {
161
+ ExecutionType = executionType,
162
+ SourceType = sourceType,
163
+ Source = FieldAsString(row, 2),
164
+ TargetType = targetType,
165
+ Target = FieldAsString(row, 3),
166
+ Win64 = (caType & WindowsInstallerConstants.MsidbCustomActionType64BitScript) == WindowsInstallerConstants.MsidbCustomActionType64BitScript,
167
+ TSAware = (caType & WindowsInstallerConstants.MsidbCustomActionTypeTSAware) == WindowsInstallerConstants.MsidbCustomActionTypeTSAware,
168
+ Impersonate = (caType & WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate) != WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate,
169
+ IgnoreResult = (caType & WindowsInstallerConstants.MsidbCustomActionTypeContinue) == WindowsInstallerConstants.MsidbCustomActionTypeContinue,
170
+ Hidden = (caType & WindowsInstallerConstants.MsidbCustomActionTypeHideTarget) == WindowsInstallerConstants.MsidbCustomActionTypeHideTarget,
171
+ Async = (caType & WindowsInstallerConstants.MsidbCustomActionTypeAsync) == WindowsInstallerConstants.MsidbCustomActionTypeAsync,
172
+ };
173
+ }
174
152
- return new FeatureTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
153
- {
154
- Feature_Parent = FieldAsString(row, 1),
155
- Title = FieldAsString(row, 2),
156
- Description = FieldAsString(row, 3),
157
- Display = FieldAsInt(row, 4), // BUGBUGBUG: FieldAsNullableInt(row, 4),
158
- Level = FieldAsInt(row, 5),
159
- Directory_ = FieldAsString(row, 6),
160
- DisallowAbsent = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent) == WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent,
161
- DisallowAdvertise = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise,
162
- InstallDefault = installDefault,
163
- TypicalDefault = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise ? FeatureTypicalDefault.Advertise : FeatureTypicalDefault.Install,
164
- };
175
+ case "Directory":
176
+ {
177
+ var id = FieldAsString(row, 0);
178
+ var splits = SplitDefaultDir(FieldAsString(row, 2));
179
+
180
+ var tuple = new DirectoryTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, id))
181
+ {
182
+ ParentDirectoryRef = FieldAsString(row, 1),
183
+ Name = splits[0],
184
+ ShortName = splits[1],
185
+ SourceName = splits[2],
186
+ SourceShortName = splits[3]
187
+ };
188
+
189
+ if (wixDirectoryById.TryGetValue(id, out var wixDirectoryRow))
190
+ {
191
+ tuple.ComponentGuidGenerationSeed = FieldAsString(wixDirectoryRow, 1);
192
}
193
167
- case "FeatureComponents":
168
- return DefaultTupleFromRow(typeof(FeatureComponentsTuple), row, columnZeroIsId: false);
169
- case "File":
170
- {
171
- var attributes = FieldAsNullableInt(row, 6);
172
- var readOnly = (attributes & WindowsInstallerConstants.MsidbFileAttributesReadOnly) == WindowsInstallerConstants.MsidbFileAttributesReadOnly;
173
- var hidden = (attributes & WindowsInstallerConstants.MsidbFileAttributesHidden) == WindowsInstallerConstants.MsidbFileAttributesHidden;
174
- var system = (attributes & WindowsInstallerConstants.MsidbFileAttributesSystem) == WindowsInstallerConstants.MsidbFileAttributesSystem;
175
- var vital = (attributes & WindowsInstallerConstants.MsidbFileAttributesVital) == WindowsInstallerConstants.MsidbFileAttributesVital;
176
- var checksum = (attributes & WindowsInstallerConstants.MsidbFileAttributesChecksum) == WindowsInstallerConstants.MsidbFileAttributesChecksum;
177
- bool? compressed = null;
178
- if ((attributes & WindowsInstallerConstants.MsidbFileAttributesNoncompressed) == WindowsInstallerConstants.MsidbFileAttributesNoncompressed)
179
- {
180
- compressed = false;
181
- }
182
- else if ((attributes & WindowsInstallerConstants.MsidbFileAttributesCompressed) == WindowsInstallerConstants.MsidbFileAttributesCompressed)
183
- {
184
- compressed = true;
185
- }
194
+ return tuple;
195
+ }
196
+ case "DrLocator":
197
+ return DefaultTupleFromRow(typeof(DrLocatorTuple), row, columnZeroIsId: false);
198
+ case "DuplicateFile":
199
+ return DefaultTupleFromRow(typeof(DuplicateFileTuple), row, columnZeroIsId: true);
200
+ case "Error":
201
+ return DefaultTupleFromRow(typeof(ErrorTuple), row, columnZeroIsId: false);
202
+ case "Extension":
203
+ return DefaultTupleFromRow(typeof(ExtensionTuple), row, columnZeroIsId: false);
204
+ case "Feature":
205
+ {
206
+ var attributes = FieldAsInt(row, 7);
207
+ var installDefault = FeatureInstallDefault.Local;
208
+ if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFollowParent) == WindowsInstallerConstants.MsidbFeatureAttributesFollowParent)
209
+ {
210
+ installDefault = FeatureInstallDefault.FollowParent;
211
+ }
212
+ else if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorSource) == WindowsInstallerConstants.MsidbFeatureAttributesFavorSource)
213
+ {
214
+ installDefault = FeatureInstallDefault.Source;
215
+ }
216
187
- return new FileTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
188
- {
189
- Component_ = FieldAsString(row, 1),
190
- LongFileName = FieldAsString(row, 2),
191
- FileSize = FieldAsInt(row, 3),
192
- Version = FieldAsString(row, 4),
193
- Language = FieldAsString(row, 5),
194
- ReadOnly = readOnly,
195
- Hidden = hidden,
196
- System = system,
197
- Vital = vital,
198
- Checksum = checksum,
199
- Compressed = compressed,
200
- };
217
+ return new FeatureTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
218
+ {
219
+ ParentFeatureRef = FieldAsString(row, 1),
220
+ Title = FieldAsString(row, 2),
221
+ Description = FieldAsString(row, 3),
222
+ Display = FieldAsInt(row, 4), // BUGBUGBUG: FieldAsNullableInt(row, 4),
223
+ Level = FieldAsInt(row, 5),
224
+ DirectoryRef = FieldAsString(row, 6),
225
+ DisallowAbsent = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent) == WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent,
226
+ DisallowAdvertise = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise,
227
+ InstallDefault = installDefault,
228
+ TypicalDefault = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise ? FeatureTypicalDefault.Advertise : FeatureTypicalDefault.Install,
229
+ };
230
+ }
231
+
232
+ case "FeatureComponents":
233
+ return DefaultTupleFromRow(typeof(FeatureComponentsTuple), row, columnZeroIsId: false);
234
+ case "File":
235
+ {
236
+ var attributes = FieldAsNullableInt(row, 6);
237
+ var readOnly = (attributes & WindowsInstallerConstants.MsidbFileAttributesReadOnly) == WindowsInstallerConstants.MsidbFileAttributesReadOnly;
238
+ var hidden = (attributes & WindowsInstallerConstants.MsidbFileAttributesHidden) == WindowsInstallerConstants.MsidbFileAttributesHidden;
239
+ var system = (attributes & WindowsInstallerConstants.MsidbFileAttributesSystem) == WindowsInstallerConstants.MsidbFileAttributesSystem;
240
+ var vital = (attributes & WindowsInstallerConstants.MsidbFileAttributesVital) == WindowsInstallerConstants.MsidbFileAttributesVital;
241
+ var checksum = (attributes & WindowsInstallerConstants.MsidbFileAttributesChecksum) == WindowsInstallerConstants.MsidbFileAttributesChecksum;
242
+ bool? compressed = null;
243
+ if ((attributes & WindowsInstallerConstants.MsidbFileAttributesNoncompressed) == WindowsInstallerConstants.MsidbFileAttributesNoncompressed)
244
+ {
245
+ compressed = false;
246
+ }
247
+ else if ((attributes & WindowsInstallerConstants.MsidbFileAttributesCompressed) == WindowsInstallerConstants.MsidbFileAttributesCompressed)
248
+ {
249
+ compressed = true;
250
}
251
203
- case "Font":
204
- return DefaultTupleFromRow(typeof(FontTuple), row, columnZeroIsId: false);
205
- case "Icon":
206
- return DefaultTupleFromRow(typeof(IconTuple), row, columnZeroIsId: false);
207
- case "InstallExecuteSequence":
208
- return DefaultTupleFromRow(typeof(InstallExecuteSequenceTuple), row, columnZeroIsId: false);
209
- case "LockPermissions":
210
- return DefaultTupleFromRow(typeof(LockPermissionsTuple), row, columnZeroIsId: false);
211
- case "Media":
212
- return DefaultTupleFromRow(typeof(MediaTuple), row, columnZeroIsId: false);
213
- case "MIME":
214
- return DefaultTupleFromRow(typeof(MIMETuple), row, columnZeroIsId: false);
215
- case "MoveFile":
216
- return DefaultTupleFromRow(typeof(MoveFileTuple), row, columnZeroIsId: false);
217
- case "MsiAssembly":
218
- return DefaultTupleFromRow(typeof(MsiAssemblyTuple), row, columnZeroIsId: false);
219
- case "MsiShortcutProperty":
220
- return DefaultTupleFromRow(typeof(MsiShortcutPropertyTuple), row, columnZeroIsId: false);
221
- case "ProgId":
222
- return DefaultTupleFromRow(typeof(ProgIdTuple), row, columnZeroIsId: false);
223
- case "Property":
224
- return DefaultTupleFromRow(typeof(PropertyTuple), row, columnZeroIsId: false);
225
- case "PublishComponent":
226
- return DefaultTupleFromRow(typeof(PublishComponentTuple), row, columnZeroIsId: false);
227
- case "Registry":
228
- {
229
- var value = FieldAsString(row, 4);
230
- var valueType = RegistryValueType.String;
231
- var valueAction = RegistryValueActionType.Write;
232
-
233
- if (!String.IsNullOrEmpty(value))
234
- {
235
- if (value.StartsWith("#x", StringComparison.Ordinal))
236
- {
237
- valueType = RegistryValueType.Binary;
238
- value = value.Substring(2);
239
- }
240
- else if (value.StartsWith("#%", StringComparison.Ordinal))
241
- {
242
- valueType = RegistryValueType.Expandable;
243
- value = value.Substring(2);
244
- }
245
- else if (value.StartsWith("#", StringComparison.Ordinal))
246
- {
247
- valueType = RegistryValueType.Integer;
248
- value = value.Substring(1);
249
- }
250
- else if (value.StartsWith("[~]", StringComparison.Ordinal) && value.EndsWith("[~]", StringComparison.Ordinal))
251
- {
252
- value = value.Substring(3, value.Length - 6);
253
- valueType = RegistryValueType.MultiString;
254
- valueAction = RegistryValueActionType.Write;
255
- }
256
- else if (value.StartsWith("[~]", StringComparison.Ordinal))
257
- {
258
- value = value.Substring(3);
259
- valueType = RegistryValueType.MultiString;
260
- valueAction = RegistryValueActionType.Append;
261
- }
262
- else if (value.EndsWith("[~]", StringComparison.Ordinal))
263
- {
264
- value = value.Substring(0, value.Length - 3);
265
- valueType = RegistryValueType.MultiString;
266
- valueAction = RegistryValueActionType.Prepend;
267
- }
268
- }
252
+ var id = FieldAsString(row, 0);
253
270
- return new RegistryTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
271
- {
272
- Root = (RegistryRootType)FieldAsInt(row, 1),
273
- Key = FieldAsString(row, 2),
274
- Name = FieldAsString(row, 3),
275
- Value = value,
276
- Component_ = FieldAsString(row, 5),
277
- ValueAction = valueAction,
278
- ValueType = valueType,
279
- };
254
+ var tuple = new FileTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, id))
255
+ {
256
+ ComponentRef = FieldAsString(row, 1),
257
+ Name = FieldAsString(row, 2),
258
+ FileSize = FieldAsInt(row, 3),
259
+ Version = FieldAsString(row, 4),
260
+ Language = FieldAsString(row, 5),
261
+ ReadOnly = readOnly,
262
+ Hidden = hidden,
263
+ System = system,
264
+ Vital = vital,
265
+ Checksum = checksum,
266
+ Compressed = compressed,
267
+ };
268
+
269
+ if (bindPathsById.TryGetValue(id, out var bindPathRow))
270
+ {
271
+ tuple.BindPath = FieldAsString(bindPathRow, 1) ?? String.Empty;
272
}
273
282
- case "RegLocator":
283
- return DefaultTupleFromRow(typeof(RegLocatorTuple), row, columnZeroIsId: false);
284
- case "RemoveFile":
285
- return DefaultTupleFromRow(typeof(RemoveFileTuple), row, columnZeroIsId: false);
286
- case "RemoveRegistry":
274
+ if (fontsById.TryGetValue(id, out var fontRow))
275
{
288
- return new RemoveRegistryTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
289
- {
290
- Action = RemoveRegistryActionType.RemoveOnInstall,
291
- Root = (RegistryRootType)FieldAsInt(row, 1),
292
- Key = FieldAsString(row, 2),
293
- Name = FieldAsString(row, 3),
294
- Component_ = FieldAsString(row, 4),
295
- };
276
+ tuple.FontTitle = FieldAsString(fontRow, 1) ?? String.Empty;
277
}
278
298
- case "ReserveCost":
299
- return DefaultTupleFromRow(typeof(ReserveCostTuple), row, columnZeroIsId: false);
300
- case "ServiceControl":
279
+ if (selfRegById.TryGetValue(id, out var selfRegRow))
280
{
302
- var events = FieldAsInt(row, 2);
303
- var wait = FieldAsNullableInt(row, 4);
304
- return new ServiceControlTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
305
- {
306
- Name = FieldAsString(row, 1),
307
- Arguments = FieldAsString(row, 3),
308
- Wait = !wait.HasValue || wait.Value == 1,
309
- Component_ = FieldAsString(row, 5),
310
- InstallRemove = (events & WindowsInstallerConstants.MsidbServiceControlEventDelete) == WindowsInstallerConstants.MsidbServiceControlEventDelete,
311
- UninstallRemove = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete) == WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete,
312
- InstallStart = (events & WindowsInstallerConstants.MsidbServiceControlEventStart) == WindowsInstallerConstants.MsidbServiceControlEventStart,
313
- UninstallStart = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallStart) == WindowsInstallerConstants.MsidbServiceControlEventUninstallStart,
314
- InstallStop = (events & WindowsInstallerConstants.MsidbServiceControlEventStop) == WindowsInstallerConstants.MsidbServiceControlEventStop,
315
- UninstallStop = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallStop) == WindowsInstallerConstants.MsidbServiceControlEventUninstallStop,
316
- };
281
+ tuple.SelfRegCost = FieldAsNullableInt(selfRegRow, 1) ?? 0;
282
}
283
319
- case "ServiceInstall":
320
- return DefaultTupleFromRow(typeof(ServiceInstallTuple), row, columnZeroIsId: true);
321
- case "Shortcut":
322
- return DefaultTupleFromRow(typeof(ShortcutTuple), row, columnZeroIsId: true);
323
- case "Signature":
324
- return DefaultTupleFromRow(typeof(SignatureTuple), row, columnZeroIsId: false);
325
- case "Upgrade":
284
+ return tuple;
285
+ }
286
+ case "Font":
287
+ return null;
288
+ case "Icon":
289
+ return DefaultTupleFromRow(typeof(IconTuple), row, columnZeroIsId: true);
290
+ case "InstallExecuteSequence":
291
+ return DefaultTupleFromRow(typeof(InstallExecuteSequenceTuple), row, columnZeroIsId: false);
292
+ case "LockPermissions":
293
+ return DefaultTupleFromRow(typeof(LockPermissionsTuple), row, columnZeroIsId: false);
294
+ case "Media":
295
+ {
296
+ var diskId = FieldAsInt(row, 0);
297
+ var tuple = new MediaTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, diskId))
298
{
327
- var attributes = FieldAsInt(row, 4);
328
- return new UpgradeTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
329
- {
330
- UpgradeCode = FieldAsString(row, 0),
331
- VersionMin = FieldAsString(row, 1),
332
- VersionMax = FieldAsString(row, 2),
333
- Language = FieldAsString(row, 3),
334
- Remove = FieldAsString(row, 5),
335
- ActionProperty = FieldAsString(row, 6),
336
- MigrateFeatures = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures) == WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures,
337
- OnlyDetect = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect) == WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect,
338
- IgnoreRemoveFailures = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure) == WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure,
339
- VersionMinInclusive = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive,
340
- VersionMaxInclusive = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive,
341
- ExcludeLanguages = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive,
342
- };
299
+ DiskId = diskId,
300
+ LastSequence = FieldAsNullableInt(row, 1),
301
+ DiskPrompt = FieldAsString(row, 2),
302
+ Cabinet = FieldAsString(row, 3),
303
+ VolumeLabel = FieldAsString(row, 4),
304
+ Source = FieldAsString(row, 5)
305
+ };
306
+
307
+ if (wixMediaByDiskId.TryGetValue(diskId, out var wixMediaRow))
308
+ {
309
+ var compressionLevel = FieldAsString(wixMediaRow, 1);
310
+
311
+ tuple.CompressionLevel = String.IsNullOrEmpty(compressionLevel) ? null : (CompressionLevel?)Enum.Parse(typeof(CompressionLevel), compressionLevel, true);
312
+ tuple.Layout = wixMediaRow.Layout;
313
}
314
345
- case "Verb":
346
- return DefaultTupleFromRow(typeof(VerbTuple), row, columnZeroIsId: false);
347
- //case "WixAction":
348
- // return new WixActionTuple(SourceLineNumber4(row.SourceLineNumbers))
349
- // {
350
- // SequenceTable = (SequenceTable)Enum.Parse(typeof(SequenceTable), FieldAsString(row, 0)),
351
- // Action = FieldAsString(row, 1),
352
- // Condition = FieldAsString(row, 2),
353
- // Sequence = FieldAsInt(row, 3),
354
- // Before = FieldAsString(row, 4),
355
- // After = FieldAsString(row, 5),
356
- // Overridable = FieldAsNullableInt(row, 6) != 0,
357
- // };
358
- case "WixFile":
359
- var assemblyAttributes3 = FieldAsNullableInt(row, 1);
360
- return new WixFileTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
315
+ return tuple;
316
+ }
317
+ case "MIME":
318
+ return DefaultTupleFromRow(typeof(MIMETuple), row, columnZeroIsId: false);
319
+ case "ModuleIgnoreTable":
320
+ return DefaultTupleFromRow(typeof(ModuleIgnoreTableTuple), row, columnZeroIsId: true);
321
+ case "MoveFile":
322
+ return DefaultTupleFromRow(typeof(MoveFileTuple), row, columnZeroIsId: true);
323
+ case "MsiAssembly":
324
+ return DefaultTupleFromRow(typeof(MsiAssemblyTuple), row, columnZeroIsId: false);
325
+ case "MsiLockPermissionsEx":
326
+ return DefaultTupleFromRow(typeof(MsiLockPermissionsExTuple), row, columnZeroIsId: true);
327
+ case "MsiShortcutProperty":
328
+ return DefaultTupleFromRow(typeof(MsiShortcutPropertyTuple), row, columnZeroIsId: true);
329
+ case "ODBCDataSource":
330
+ return DefaultTupleFromRow(typeof(ODBCDataSourceTuple), row, columnZeroIsId: true);
331
+ case "ODBCDriver":
332
+ return DefaultTupleFromRow(typeof(ODBCDriverTuple), row, columnZeroIsId: true);
333
+ case "ODBCTranslator":
334
+ return DefaultTupleFromRow(typeof(ODBCTranslatorTuple), row, columnZeroIsId: true);
335
+ case "ProgId":
336
+ return DefaultTupleFromRow(typeof(ProgIdTuple), row, columnZeroIsId: false);
337
+ case "Property":
338
+ return DefaultTupleFromRow(typeof(PropertyTuple), row, columnZeroIsId: true);
339
+ case "PublishComponent":
340
+ return DefaultTupleFromRow(typeof(PublishComponentTuple), row, columnZeroIsId: false);
341
+ case "Registry":
342
+ {
343
+ var value = FieldAsString(row, 4);
344
+ var valueType = RegistryValueType.String;
345
+ var valueAction = RegistryValueActionType.Write;
346
+
347
+ if (!String.IsNullOrEmpty(value))
348
+ {
349
+ if (value.StartsWith("#x", StringComparison.Ordinal))
350
{
362
- AssemblyType = assemblyAttributes3 == 0 ? FileAssemblyType.DotNetAssembly : assemblyAttributes3 == 1 ? FileAssemblyType.Win32Assembly : FileAssemblyType.NotAnAssembly,
363
- File_AssemblyManifest = FieldAsString(row, 2),
364
- File_AssemblyApplication = FieldAsString(row, 3),
365
- Directory_ = FieldAsString(row, 4),
366
- DiskId = FieldAsInt(row, 5), // TODO: BUGBUGBUG: AB#2626: DiskId is nullable in WiX v3.
367
- Source = new IntermediateFieldPathValue() { Path = FieldAsString(row, 6) },
368
- ProcessorArchitecture = FieldAsString(row, 7),
369
- PatchGroup = FieldAsInt(row, 8),
370
- Attributes = FieldAsInt(row, 9),
371
- };
372
- case "WixProperty":
373
- {
374
- var attributes = FieldAsInt(row, 1);
375
- return new WixPropertyTuple(SourceLineNumber4(row.SourceLineNumbers))
351
+ valueType = RegistryValueType.Binary;
352
+ value = value.Substring(2);
353
+ }
354
+ else if (value.StartsWith("#%", StringComparison.Ordinal))
355
+ {
356
+ valueType = RegistryValueType.Expandable;
357
+ value = value.Substring(2);
358
+ }
359
+ else if (value.StartsWith("#", StringComparison.Ordinal))
360
+ {
361
+ valueType = RegistryValueType.Integer;
362
+ value = value.Substring(1);
363
+ }
364
+ else if (value.StartsWith("[~]", StringComparison.Ordinal) && value.EndsWith("[~]", StringComparison.Ordinal))
365
+ {
366
+ value = value.Substring(3, value.Length - 6);
367
+ valueType = RegistryValueType.MultiString;
368
+ valueAction = RegistryValueActionType.Write;
369
+ }
370
+ else if (value.StartsWith("[~]", StringComparison.Ordinal))
371
+ {
372
+ value = value.Substring(3);
373
+ valueType = RegistryValueType.MultiString;
374
+ valueAction = RegistryValueActionType.Append;
375
+ }
376
+ else if (value.EndsWith("[~]", StringComparison.Ordinal))
377
{
377
- Property_ = FieldAsString(row, 0),
378
- Admin = (attributes & 0x1) == 0x1,
379
- Hidden = (attributes & 0x2) == 0x2,
380
- Secure = (attributes & 0x4) == 0x4,
381
- };
378
+ value = value.Substring(0, value.Length - 3);
379
+ valueType = RegistryValueType.MultiString;
380
+ valueAction = RegistryValueActionType.Prepend;
381
+ }
382
}
383
384
- default:
385
- return GenericTupleFromCustomRow(row, columnZeroIsId: false);
384
+ return new RegistryTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
385
+ {
386
+ Root = (RegistryRootType)FieldAsInt(row, 1),
387
+ Key = FieldAsString(row, 2),
388
+ Name = FieldAsString(row, 3),
389
+ Value = value,
390
+ ComponentRef = FieldAsString(row, 5),
391
+ ValueAction = valueAction,
392
+ ValueType = valueType,
393
+ };
394
+ }
395
+ case "RegLocator":
396
+ {
397
+ var type = FieldAsInt(row, 4);
398
+
399
+ return new RegLocatorTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
400
+ {
401
+ Root = (RegistryRootType)FieldAsInt(row, 1),
402
+ Key = FieldAsString(row, 2),
403
+ Name = FieldAsString(row, 3),
404
+ Type = (RegLocatorType)(type & 0xF),
405
+ Win64 = (type & WindowsInstallerConstants.MsidbLocatorType64bit) == WindowsInstallerConstants.MsidbLocatorType64bit
406
+ };
407
+ }
408
+ case "RemoveFile":
409
+ {
410
+ var installMode = FieldAsInt(row, 4);
411
+ return new RemoveFileTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
412
+ {
413
+ ComponentRef = FieldAsString(row, 1),
414
+ FileName = FieldAsString(row, 2),
415
+ DirProperty = FieldAsString(row, 3),
416
+ OnInstall = (installMode & WindowsInstallerConstants.MsidbRemoveFileInstallModeOnInstall) == WindowsInstallerConstants.MsidbRemoveFileInstallModeOnInstall ? (bool?)true : null,
417
+ OnUninstall = (installMode & WindowsInstallerConstants.MsidbRemoveFileInstallModeOnRemove) == WindowsInstallerConstants.MsidbRemoveFileInstallModeOnRemove ? (bool?)true : null
418
+ };
419
+ }
420
+ case "RemoveRegistry":
421
+ {
422
+ return new RemoveRegistryTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
423
+ {
424
+ Action = RemoveRegistryActionType.RemoveOnInstall,
425
+ Root = (RegistryRootType)FieldAsInt(row, 1),
426
+ Key = FieldAsString(row, 2),
427
+ Name = FieldAsString(row, 3),
428
+ ComponentRef = FieldAsString(row, 4),
429
+ };
430
+ }
431
+
432
+ case "ReserveCost":
433
+ return DefaultTupleFromRow(typeof(ReserveCostTuple), row, columnZeroIsId: true);
434
+ case "SelfReg":
435
+ return null;
436
+ case "ServiceControl":
437
+ {
438
+ var events = FieldAsInt(row, 2);
439
+ var wait = FieldAsNullableInt(row, 4);
440
+ return new ServiceControlTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
441
+ {
442
+ Name = FieldAsString(row, 1),
443
+ Arguments = FieldAsString(row, 3),
444
+ Wait = !wait.HasValue || wait.Value == 1,
445
+ ComponentRef = FieldAsString(row, 5),
446
+ InstallRemove = (events & WindowsInstallerConstants.MsidbServiceControlEventDelete) == WindowsInstallerConstants.MsidbServiceControlEventDelete,
447
+ UninstallRemove = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete) == WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete,
448
+ InstallStart = (events & WindowsInstallerConstants.MsidbServiceControlEventStart) == WindowsInstallerConstants.MsidbServiceControlEventStart,
449
+ UninstallStart = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallStart) == WindowsInstallerConstants.MsidbServiceControlEventUninstallStart,
450
+ InstallStop = (events & WindowsInstallerConstants.MsidbServiceControlEventStop) == WindowsInstallerConstants.MsidbServiceControlEventStop,
451
+ UninstallStop = (events & WindowsInstallerConstants.MsidbServiceControlEventUninstallStop) == WindowsInstallerConstants.MsidbServiceControlEventUninstallStop,
452
+ };
453
+ }
454
+
455
+ case "ServiceInstall":
456
+ return DefaultTupleFromRow(typeof(ServiceInstallTuple), row, columnZeroIsId: true);
457
+ case "Shortcut":
458
+ {
459
+ var splitName = FieldAsString(row, 2).Split('|');
460
+
461
+ return new ShortcutTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
462
+ {
463
+ DirectoryRef = FieldAsString(row, 1),
464
+ Name = splitName.Length > 1 ? splitName[1] : splitName[0],
465
+ ShortName = splitName.Length > 1 ? splitName[0] : null,
466
+ ComponentRef = FieldAsString(row, 3),
467
+ Target = FieldAsString(row, 4),
468
+ Arguments = FieldAsString(row, 5),
469
+ Description = FieldAsString(row, 6),
470
+ Hotkey = FieldAsNullableInt(row, 7),
471
+ IconRef = FieldAsString(row, 8),
472
+ IconIndex = FieldAsNullableInt(row, 9),
473
+ Show = (ShortcutShowType?)FieldAsNullableInt(row, 10),
474
+ WorkingDirectory = FieldAsString(row, 11),
475
+ DisplayResourceDll = FieldAsString(row, 12),
476
+ DisplayResourceId = FieldAsNullableInt(row, 13),
477
+ DescriptionResourceDll = FieldAsString(row, 14),
478
+ DescriptionResourceId= FieldAsNullableInt(row, 15),
479
+ };
480
+ }
481
+ case "Signature":
482
+ return DefaultTupleFromRow(typeof(SignatureTuple), row, columnZeroIsId: false);
483
+ case "UIText":
484
+ return DefaultTupleFromRow(typeof(UITextTuple), row, columnZeroIsId: true);
485
+ case "Upgrade":
486
+ {
487
+ var attributes = FieldAsInt(row, 4);
488
+ return new UpgradeTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
489
+ {
490
+ UpgradeCode = FieldAsString(row, 0),
491
+ VersionMin = FieldAsString(row, 1),
492
+ VersionMax = FieldAsString(row, 2),
493
+ Language = FieldAsString(row, 3),
494
+ Remove = FieldAsString(row, 5),
495
+ ActionProperty = FieldAsString(row, 6),
496
+ MigrateFeatures = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures) == WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures,
497
+ OnlyDetect = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect) == WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect,
498
+ IgnoreRemoveFailures = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure) == WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure,
499
+ VersionMinInclusive = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive,
500
+ VersionMaxInclusive = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive,
501
+ ExcludeLanguages = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive,
502
+ };
503
+ }
504
+ case "Verb":
505
+ return DefaultTupleFromRow(typeof(VerbTuple), row, columnZeroIsId: false);
506
+ case "WixAction":
507
+ var sequenceTable = FieldAsString(row, 0);
508
+ return new WixActionTuple(SourceLineNumber4(row.SourceLineNumbers))
509
+ {
510
+ SequenceTable = (SequenceTable)Enum.Parse(typeof(SequenceTable), sequenceTable == "AdvtExecuteSequence" ? nameof(SequenceTable.AdvertiseExecuteSequence) : sequenceTable),
511
+ Action = FieldAsString(row, 1),
512
+ Condition = FieldAsString(row, 2),
513
+ Sequence = FieldAsNullableInt(row, 3),
514
+ Before = FieldAsString(row, 4),
515
+ After = FieldAsString(row, 5),
516
+ Overridable = FieldAsNullableInt(row, 6) != 0,
517
+ };
518
+ case "WixBootstrapperApplication":
519
+ return DefaultTupleFromRow(typeof(WixBootstrapperApplicationTuple), row, columnZeroIsId: true);
520
+ case "WixBundleContainer":
521
+ return DefaultTupleFromRow(typeof(WixBundleContainerTuple), row, columnZeroIsId: true);
522
+ case "WixBundleVariable":
523
+ return DefaultTupleFromRow(typeof(WixBundleVariableTuple), row, columnZeroIsId: true);
524
+ case "WixChainItem":
525
+ return DefaultTupleFromRow(typeof(WixChainItemTuple), row, columnZeroIsId: true);
526
+ case "WixCustomTable":
527
+ return DefaultTupleFromRow(typeof(WixCustomTableTuple), row, columnZeroIsId: true);
528
+ case "WixDeltaPatchFile":
529
+ return DefaultTupleFromRow(typeof(WixDeltaPatchFileTuple), row, columnZeroIsId: true);
530
+ case "WixDirectory":
531
+ return null;
532
+ case "WixFile":
533
+ var assemblyAttributes3 = FieldAsNullableInt(row, 1);
534
+ return new WixFileTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0)))
535
+ {
536
+ AssemblyType = assemblyAttributes3 == 0 ? FileAssemblyType.DotNetAssembly : assemblyAttributes3 == 1 ? FileAssemblyType.Win32Assembly : FileAssemblyType.NotAnAssembly,
537
+ AssemblyManifestFileRef = FieldAsString(row, 2),
538
+ AssemblyApplicationFileRef = FieldAsString(row, 3),
539
+ DirectoryRef = FieldAsString(row, 4),
540
+ DiskId = FieldAsNullableInt(row, 5) ?? 0,
541
+ Source = new IntermediateFieldPathValue() { Path = FieldAsString(row, 6) },
542
+ ProcessorArchitecture = FieldAsString(row, 7),
543
+ PatchGroup = FieldAsInt(row, 8),
544
+ Attributes = FieldAsInt(row, 9),
545
+ PatchAttributes = (PatchAttributeType)FieldAsInt(row, 10),
546
+ };
547
+ case "WixInstanceTransforms":
548
+ return DefaultTupleFromRow(typeof(WixInstanceTransformsTuple), row, columnZeroIsId: true);
549
+ case "WixMedia":
550
+ return null;
551
+ case "WixMerge":
552
+ return DefaultTupleFromRow(typeof(WixMergeTuple), row, columnZeroIsId: true);
553
+ case "WixPatchBaseline":
554
+ return DefaultTupleFromRow(typeof(WixPatchBaselineTuple), row, columnZeroIsId: true);
555
+ case "WixProperty":
556
+ {
557
+ var attributes = FieldAsInt(row, 1);
558
+ return new WixPropertyTuple(SourceLineNumber4(row.SourceLineNumbers))
559
+ {
560
+ PropertyRef = FieldAsString(row, 0),
561
+ Admin = (attributes & 0x1) == 0x1,
562
+ Hidden = (attributes & 0x2) == 0x2,
563
+ Secure = (attributes & 0x4) == 0x4,
564
+ };
565
+ }
566
+ case "WixSuppressModularization":
567
+ return DefaultTupleFromRow(typeof(WixSuppressModularizationTuple), row, columnZeroIsId: true);
568
+ case "WixUI":
569
+ return DefaultTupleFromRow(typeof(WixUITuple), row, columnZeroIsId: true);
570
+ case "WixVariable":
571
+ return DefaultTupleFromRow(typeof(WixVariableTuple), row, columnZeroIsId: true);
572
+ default:
573
+ return GenericTupleFromCustomRow(row, columnZeroIsId: false);
574
}
575
}
576
@@ -470,16 +658,16 @@ namespace WixToolset.Converters.Tupleizer
658
{
659
switch (columnType)
660
{
473
- case Wix3.ColumnType.Number:
474
- return IntermediateFieldType.Number;
475
- case Wix3.ColumnType.Object:
476
- return IntermediateFieldType.Path;
477
- case Wix3.ColumnType.Unknown:
478
- case Wix3.ColumnType.String:
479
- case Wix3.ColumnType.Localized:
480
- case Wix3.ColumnType.Preserved:
481
- default:
482
- return IntermediateFieldType.String;
661
+ case Wix3.ColumnType.Number:
662
+ return IntermediateFieldType.Number;
663
+ case Wix3.ColumnType.Object:
664
+ return IntermediateFieldType.Path;
665
+ case Wix3.ColumnType.Unknown:
666
+ case Wix3.ColumnType.String:
667
+ case Wix3.ColumnType.Localized:
668
+ case Wix3.ColumnType.Preserved:
669
+ default:
670
+ return IntermediateFieldType.String;
671
}
672
}
673
@@ -520,22 +708,22 @@ namespace WixToolset.Converters.Tupleizer
708
var column = row.Fields[i].Column;
709
switch (column.Type)
710
{
523
- case Wix3.ColumnType.String:
524
- case Wix3.ColumnType.Localized:
525
- case Wix3.ColumnType.Object:
526
- case Wix3.ColumnType.Preserved:
527
- tuple.Set(i - offset, FieldAsString(row, i));
528
- break;
529
- case Wix3.ColumnType.Number:
530
- int? nullableValue = FieldAsNullableInt(row, i);
531
- // TODO: Consider whether null values should be coerced to their default value when
532
- // a column is not nullable. For now, just pass through the null.
533
- //int value = FieldAsInt(row, i);
534
- //tuple.Set(i - offset, column.IsNullable ? nullableValue : value);
535
- tuple.Set(i - offset, nullableValue);
711
+ case Wix3.ColumnType.String:
712
+ case Wix3.ColumnType.Localized:
713
+ case Wix3.ColumnType.Object:
714
+ case Wix3.ColumnType.Preserved:
715
+ tuple.Set(i - offset, FieldAsString(row, i));
716
+ break;
717
+ case Wix3.ColumnType.Number:
718
+ int? nullableValue = FieldAsNullableInt(row, i);
719
+ // TODO: Consider whether null values should be coerced to their default value when
720
+ // a column is not nullable. For now, just pass through the null.
721
+ //int value = FieldAsInt(row, i);
722
+ //tuple.Set(i - offset, column.IsNullable ? nullableValue : value);
723
+ tuple.Set(i - offset, nullableValue);
724
+ break;
725
+ case Wix3.ColumnType.Unknown:
726
break;
537
- case Wix3.ColumnType.Unknown:
538
- break;
727
}
728
}
729
}
@@ -545,15 +733,15 @@ namespace WixToolset.Converters.Tupleizer
733
var column = row.Fields[0].Column;
734
switch (column.Type)
735
{
548
- case Wix3.ColumnType.String:
549
- case Wix3.ColumnType.Localized:
550
- case Wix3.ColumnType.Object:
551
- case Wix3.ColumnType.Preserved:
552
- return new Identifier(AccessModifier.Public, (string)row.Fields[0].Data);
553
- case Wix3.ColumnType.Number:
554
- return new Identifier(AccessModifier.Public, FieldAsInt(row, 0));
555
- default:
556
- return null;
736
+ case Wix3.ColumnType.String:
737
+ case Wix3.ColumnType.Localized:
738
+ case Wix3.ColumnType.Object:
739
+ case Wix3.ColumnType.Preserved:
740
+ return new Identifier(AccessModifier.Public, (string)row.Fields[0].Data);
741
+ case Wix3.ColumnType.Number:
742
+ return new Identifier(AccessModifier.Public, FieldAsInt(row, 0));
743
+ default:
744
+ return null;
745
}
746
}
747
@@ -561,20 +749,20 @@ namespace WixToolset.Converters.Tupleizer
749
{
750
switch (outputType)
751
{
564
- case Wix3.OutputType.Bundle:
565
- return SectionType.Bundle;
566
- case Wix3.OutputType.Module:
567
- return SectionType.Module;
568
- case Wix3.OutputType.Patch:
569
- return SectionType.Patch;
570
- case Wix3.OutputType.PatchCreation:
571
- return SectionType.PatchCreation;
572
- case Wix3.OutputType.Product:
573
- return SectionType.Product;
574
- case Wix3.OutputType.Transform:
575
- case Wix3.OutputType.Unknown:
576
- default:
577
- return SectionType.Unknown;
752
+ case Wix3.OutputType.Bundle:
753
+ return SectionType.Bundle;
754
+ case Wix3.OutputType.Module:
755
+ return SectionType.Module;
756
+ case Wix3.OutputType.Patch:
757
+ return SectionType.Patch;
758
+ case Wix3.OutputType.PatchCreation:
759
+ return SectionType.PatchCreation;
760
+ case Wix3.OutputType.Product:
761
+ return SectionType.Product;
762
+ case Wix3.OutputType.Transform:
763
+ case Wix3.OutputType.Unknown:
764
+ default:
765
+ return SectionType.Unknown;
766
}
767
}
768
@@ -605,5 +793,19 @@ namespace WixToolset.Converters.Tupleizer
793
return Convert.ToInt32(field.Data);
794
}
795
}
796
+
797
+ private static string[] SplitDefaultDir(string defaultDir)
798
+ {
799
+ var split1 = defaultDir.Split(':');
800
+ var targetSplit = split1.Length > 1 ? split1[1].Split('|') : split1[0].Split('|');
801
+ var sourceSplit = split1.Length > 1 ? split1[0].Split('|') : new[] { String.Empty };
802
+ return new[]
803
+ {
804
+ targetSplit.Length > 1 ? targetSplit[1] : targetSplit[0],
805
+ targetSplit.Length > 1 ? targetSplit[0] : null,
806
+ sourceSplit.Length > 1 ? sourceSplit[1] : sourceSplit[0],
807
+ sourceSplit.Length > 1 ? sourceSplit[0] : null
808
+ };
809
+ }
810
}
811
}
src/test/WixToolsetTest.Converters.Tupleizer/ConvertTuplesFixture.cs
+455
-292
@@ -3,6 +3,7 @@
3
namespace WixToolsetTest.Converters.Tupleizer
4
{
5
using System;
6
+ using System.Collections.Generic;
7
using System.IO;
8
using System.Linq;
9
using WixBuildTools.TestSupport;
@@ -42,350 +43,512 @@ namespace WixToolsetTest.Converters.Tupleizer
43
44
intermediate = Intermediate.Load(wixiplFile);
45
46
+ var wixMediaByDiskId = IndexWixMediaTableByDiskId(output);
47
+
48
// Dump to text for easy diffing, with some massaging to keep v3 and v4 diffable.
49
//
50
var tables = output.Tables.Cast<Wix3.Table>();
51
var wix3Dump = tables
52
.SelectMany(table => table.Rows.Cast<Wix3.Row>()
50
- .Select(row => RowToString(row)))
53
+ .SelectMany(row => RowToStrings(row, wixMediaByDiskId)))
54
+ .Where(s => !String.IsNullOrEmpty(s))
55
+ .OrderBy(s => s)
56
.ToArray();
57
58
var tuples = intermediate.Sections.SelectMany(s => s.Tuples);
54
- var wix4Dump = tuples.Select(tuple => TupleToString(tuple)).ToArray();
59
+ var wix4Dump = tuples
60
+ .SelectMany(tuple => TupleToStrings(tuple))
61
+ .OrderBy(s => s)
62
+ .ToArray();
63
64
+#if false
65
Assert.Equal(wix3Dump, wix4Dump);
66
+#else // useful when you want to diff the outputs with another diff tool.
67
+ var wix3TextDump = String.Join(Environment.NewLine, wix3Dump);
68
+ var wix4TextDump = String.Join(Environment.NewLine, wix4Dump);
69
58
- // Useful when you want to diff the outputs with another diff tool...
59
- //
60
- //var wix3TextDump = String.Join(Environment.NewLine, wix3Dump.OrderBy(val => val));
61
- //var wix4TextDump = String.Join(Environment.NewLine, wix4Dump.OrderBy(val => val));
62
- //Assert.Equal(wix3TextDump, wix4TextDump);
70
+ File.WriteAllText(Path.Combine(Path.GetTempPath(), "~3.txt"), wix3TextDump);
71
+ File.WriteAllText(Path.Combine(Path.GetTempPath(), "~4.txt"), wix4TextDump);
72
+
73
+ Assert.Equal(wix3TextDump, wix4TextDump);
74
+#endif
75
}
76
}
77
66
- private static string RowToString(Wix3.Row row)
78
+ private static Dictionary<int, Wix3.WixMediaRow> IndexWixMediaTableByDiskId(Wix3.Output output)
79
{
68
- var fields = String.Join(",", row.Fields.Select(field => field.Data?.ToString()));
80
+ var wixMediaByDiskId = new Dictionary<int, Wix3.WixMediaRow>();
81
+ var wixMediaTable = output.Tables["WixMedia"];
82
70
- // Massage output to match WiX v3 rows and v4 tuples.
71
- //
72
- switch (row.Table.Name)
83
+ if (wixMediaTable != null)
84
{
74
- case "File":
75
- var fieldValues = row.Fields.Take(7).Select(field => field.Data?.ToString()).ToArray();
76
- if (fieldValues[3] == null)
77
- {
78
- // "Somebody" sometimes writes out a null field even when the column definition says
79
- // it's non-nullable. Not naming names or anything. (SWID tags.)
80
- fieldValues[3] = "0";
81
- }
82
- fields = String.Join(",", fieldValues);
83
- break;
84
- case "WixFile":
85
- fields = String.Join(",", row.Fields.Take(8).Select(field => field.Data?.ToString()));
86
- break;
85
+ foreach (Wix3.WixMediaRow row in wixMediaTable.Rows)
86
+ {
87
+ wixMediaByDiskId.Add((int)row[0], row);
88
+ }
89
}
90
89
- return $"{row.Table.Name},{fields}";
91
+ return wixMediaByDiskId;
92
}
93
92
- private static string TupleToString(WixToolset.Data.IntermediateTuple tuple)
94
+ private static IEnumerable<string> RowToStrings(Wix3.Row row, Dictionary<int, Wix3.WixMediaRow> wixMediaByDiskId)
95
{
94
- var fields = String.Join(",", tuple.Fields.Select(field => field?.AsString()));
96
+ string fields = null;
97
96
- switch (tuple.Definition.Name)
98
+ // Massage output to match WiX v3 rows and v4 tuples.
99
+ //
100
+ switch (row.Table.Name)
101
{
98
- // Massage output to match WiX v3 rows and v4 tuples.
99
- //
100
- case "Component":
101
- {
102
- var componentTuple = (ComponentTuple)tuple;
103
- var attributes = ComponentLocation.Either == componentTuple.Location ? WindowsInstallerConstants.MsidbComponentAttributesOptional : 0;
104
- attributes |= ComponentLocation.SourceOnly == componentTuple.Location ? WindowsInstallerConstants.MsidbComponentAttributesSourceOnly : 0;
105
- attributes |= ComponentKeyPathType.Registry == componentTuple.KeyPathType ? WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath : 0;
106
- attributes |= ComponentKeyPathType.OdbcDataSource == componentTuple.KeyPathType ? WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource : 0;
107
- attributes |= componentTuple.DisableRegistryReflection ? WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection : 0;
108
- attributes |= componentTuple.NeverOverwrite ? WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite : 0;
109
- attributes |= componentTuple.Permanent ? WindowsInstallerConstants.MsidbComponentAttributesPermanent : 0;
110
- attributes |= componentTuple.SharedDllRefCount ? WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount : 0;
111
- attributes |= componentTuple.Shared ? WindowsInstallerConstants.MsidbComponentAttributesShared : 0;
112
- attributes |= componentTuple.Transitive ? WindowsInstallerConstants.MsidbComponentAttributesTransitive : 0;
113
- attributes |= componentTuple.UninstallWhenSuperseded ? WindowsInstallerConstants.MsidbComponentAttributes64bit : 0;
114
- attributes |= componentTuple.Win64 ? WindowsInstallerConstants.MsidbComponentAttributes64bit : 0;
115
-
116
- fields = String.Join(",",
117
- componentTuple.ComponentId,
118
- componentTuple.Directory_,
119
- attributes.ToString(),
120
- componentTuple.Condition,
121
- componentTuple.KeyPath
122
- );
123
- break;
124
- }
125
- case "CustomAction":
102
+ case "Directory":
103
+ var dirs = SplitDefaultDir((string)row[2]);
104
+ fields = String.Join(",", row[0], row[1], dirs[0], dirs[1], dirs[2], dirs[3]);
105
+ break;
106
+ case "File":
107
+ {
108
+ var fieldValues = row.Fields.Take(7).Select(SafeConvertField).ToArray();
109
+ if (fieldValues[3] == null)
110
{
127
- var customActionTuple = (CustomActionTuple)tuple;
128
- var type = customActionTuple.Win64 ? WindowsInstallerConstants.MsidbCustomActionType64BitScript : 0;
129
- type |= customActionTuple.TSAware ? WindowsInstallerConstants.MsidbCustomActionTypeTSAware : 0;
130
- type |= customActionTuple.Impersonate ? 0 : WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate;
131
- type |= customActionTuple.IgnoreResult ? WindowsInstallerConstants.MsidbCustomActionTypeContinue : 0;
132
- type |= customActionTuple.Hidden ? WindowsInstallerConstants.MsidbCustomActionTypeHideTarget : 0;
133
- type |= customActionTuple.Async ? WindowsInstallerConstants.MsidbCustomActionTypeAsync : 0;
134
- type |= CustomActionExecutionType.FirstSequence == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeFirstSequence : 0;
135
- type |= CustomActionExecutionType.OncePerProcess == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeOncePerProcess : 0;
136
- type |= CustomActionExecutionType.ClientRepeat == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeClientRepeat : 0;
137
- type |= CustomActionExecutionType.Deferred == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript : 0;
138
- type |= CustomActionExecutionType.Rollback == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript | WindowsInstallerConstants.MsidbCustomActionTypeRollback : 0;
139
- type |= CustomActionExecutionType.Commit == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript | WindowsInstallerConstants.MsidbCustomActionTypeCommit : 0;
140
- type |= CustomActionSourceType.File == customActionTuple.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeSourceFile : 0;
141
- type |= CustomActionSourceType.Directory == customActionTuple.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeDirectory : 0;
142
- type |= CustomActionSourceType.Property == customActionTuple.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeProperty : 0;
143
- type |= CustomActionTargetType.Dll == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeDll : 0;
144
- type |= CustomActionTargetType.Exe == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeExe : 0;
145
- type |= CustomActionTargetType.TextData == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeTextData : 0;
146
- type |= CustomActionTargetType.JScript == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeJScript : 0;
147
- type |= CustomActionTargetType.VBScript == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeVBScript : 0;
148
-
149
- fields = String.Join(",",
150
- type.ToString(),
151
- customActionTuple.Source,
152
- customActionTuple.Target,
153
- customActionTuple.PatchUninstall ? WindowsInstallerConstants.MsidbCustomActionTypePatchUninstall.ToString() : null
154
- );
155
- break;
111
+ // "Somebody" sometimes writes out a null field even when the column definition says
112
+ // it's non-nullable. Not naming names or anything. (SWID tags.)
113
+ fieldValues[3] = "0";
114
}
157
- case "Feature":
158
- {
159
- var featureTuple = (FeatureTuple)tuple;
160
- var attributes = featureTuple.DisallowAbsent ? WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent : 0;
161
- attributes |= featureTuple.DisallowAdvertise ? WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise : 0;
162
- attributes |= FeatureInstallDefault.FollowParent == featureTuple.InstallDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFollowParent : 0;
163
- attributes |= FeatureInstallDefault.Source == featureTuple.InstallDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFavorSource : 0;
164
- attributes |= FeatureTypicalDefault.Advertise == featureTuple.TypicalDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise : 0;
165
-
166
- fields = String.Join(",",
167
- featureTuple.Feature_Parent,
168
- featureTuple.Title,
169
- featureTuple.Description,
170
- featureTuple.Display.ToString(),
171
- featureTuple.Level.ToString(),
172
- featureTuple.Directory_,
173
- attributes.ToString());
174
- break;
175
- }
176
- case "File":
115
+ fields = String.Join(",", fieldValues);
116
+ break;
117
+ }
118
+ case "Media":
119
+ var compression = wixMediaByDiskId.TryGetValue((int)row[0], out var wixMedia) ? (CompressionLevel?)Enum.Parse(typeof(CompressionLevel), SafeConvertField(wixMedia.Fields[1]), true) : null;
120
+
121
+ fields = String.Join(",", row.Fields.Select(SafeConvertField));
122
+ fields = String.Join(",", fields, (int?)compression, SafeConvertField(wixMedia?.Fields[2]));
123
+ break;
124
+ case "RegLocator":
125
+ var type = (int)row[4];
126
+ fields = String.Join(",", row[0], row[1], row[2], row[3], type & 0xF, (type & 0x10) == 0x10);
127
+ break;
128
+ case "RemoveFile":
129
+ var attributes = (int)row[4];
130
+ var onInstall = (attributes & 1) == 1 ? (bool?)true : null;
131
+ var onUninstall = (attributes & 2) == 2 ? (bool?)true : null;
132
+ fields = String.Join(",", row.Fields.Take(4).Select(SafeConvertField));
133
+ fields = String.Join(",", fields, onInstall, onUninstall);
134
+ break;
135
+ case "Shortcut":
136
+ var split = ((string)row[2]).Split('|');
137
+ var afterName = String.Join(",", row.Fields.Skip(3).Select(SafeConvertField));
138
+ fields = String.Join(",", row[0], row[1], split.Length > 1 ? split[1] : split[0], split.Length > 1 ? split[0] : String.Empty, afterName);
139
+ break;
140
+ case "WixAction":
141
+ var table = (int)SequenceStringToSequenceTable(row[0]);
142
+ fields = String.Join(",", table, row[1], row[2], row[3], row[4], row[5], row[6]);
143
+ break;
144
+ case "WixFile":
145
+ {
146
+ var fieldValues = row.Fields.Take(10).Select(SafeConvertField).ToArray();
147
+ if (fieldValues[8] == null)
148
{
178
- var fileTuple = (FileTuple)tuple;
179
- fields = String.Join(",",
180
- fileTuple.Component_,
181
- fileTuple.LongFileName,
182
- fileTuple.FileSize.ToString(),
183
- fileTuple.Version,
184
- fileTuple.Language,
185
- ((fileTuple.ReadOnly ? WindowsInstallerConstants.MsidbFileAttributesReadOnly : 0)
186
- | (fileTuple.Hidden ? WindowsInstallerConstants.MsidbFileAttributesHidden : 0)
187
- | (fileTuple.System ? WindowsInstallerConstants.MsidbFileAttributesSystem : 0)
188
- | (fileTuple.Vital ? WindowsInstallerConstants.MsidbFileAttributesVital : 0)
189
- | (fileTuple.Checksum ? WindowsInstallerConstants.MsidbFileAttributesChecksum : 0)
190
- | ((fileTuple.Compressed.HasValue && fileTuple.Compressed.Value) ? WindowsInstallerConstants.MsidbFileAttributesCompressed : 0)
191
- | ((fileTuple.Compressed.HasValue && !fileTuple.Compressed.Value) ? WindowsInstallerConstants.MsidbFileAttributesNoncompressed : 0))
192
- .ToString());
193
- break;
149
+ // "Somebody" sometimes writes out a null field even when the column definition says
150
+ // it's non-nullable. Not naming names or anything. (SWID tags.)
151
+ fieldValues[8] = "0";
152
}
153
+ fields = String.Join(",", fieldValues);
154
+ break;
155
+ }
156
+ case "WixMedia":
157
+ break;
158
+ default:
159
+ fields = String.Join(",", row.Fields.Select(SafeConvertField));
160
+ break;
161
+ }
162
196
- case "Registry":
197
- {
198
- var registryTuple = (RegistryTuple)tuple;
199
- var value = registryTuple.Value;
200
-
201
- switch (registryTuple.ValueType)
202
- {
203
- case RegistryValueType.Binary:
204
- value = String.Concat("#x", value);
205
- break;
206
- case RegistryValueType.Expandable:
207
- value = String.Concat("#%", value);
208
- break;
209
- case RegistryValueType.Integer:
210
- value = String.Concat("#", value);
211
- break;
212
- case RegistryValueType.MultiString:
213
- switch (registryTuple.ValueAction)
214
- {
215
- case RegistryValueActionType.Append:
216
- value = String.Concat("[~]", value);
217
- break;
218
- case RegistryValueActionType.Prepend:
219
- value = String.Concat(value, "[~]");
220
- break;
221
- case RegistryValueActionType.Write:
222
- default:
223
- if (null != value && -1 == value.IndexOf("[~]", StringComparison.Ordinal))
224
- {
225
- value = String.Concat("[~]", value, "[~]");
226
- }
227
- break;
228
- }
229
- break;
230
- case RegistryValueType.String:
231
- // escape the leading '#' character for string registry keys
232
- if (null != value && value.StartsWith("#", StringComparison.Ordinal))
233
- {
234
- value = String.Concat("#", value);
235
- }
236
- break;
237
- }
163
+ if (fields != null)
164
+ {
165
+ yield return $"{row.Table.Name}:{fields}";
166
+ }
167
+ }
168
239
- fields = String.Join(",",
240
- ((int)registryTuple.Root).ToString(),
241
- registryTuple.Key,
242
- registryTuple.Name,
243
- value,
244
- registryTuple.Component_
245
- );
246
- break;
247
- }
169
+ private static IEnumerable<string> TupleToStrings(IntermediateTuple tuple)
170
+ {
171
+ string fields;
172
+ switch (tuple.Definition.Name)
173
+ {
174
+ // Massage output to match WiX v3 rows and v4 tuples.
175
+ //
176
+ case "Component":
177
+ {
178
+ var componentTuple = (ComponentTuple)tuple;
179
+ var attributes = ComponentLocation.Either == componentTuple.Location ? WindowsInstallerConstants.MsidbComponentAttributesOptional : 0;
180
+ attributes |= ComponentLocation.SourceOnly == componentTuple.Location ? WindowsInstallerConstants.MsidbComponentAttributesSourceOnly : 0;
181
+ attributes |= ComponentKeyPathType.Registry == componentTuple.KeyPathType ? WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath : 0;
182
+ attributes |= ComponentKeyPathType.OdbcDataSource == componentTuple.KeyPathType ? WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource : 0;
183
+ attributes |= componentTuple.DisableRegistryReflection ? WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection : 0;
184
+ attributes |= componentTuple.NeverOverwrite ? WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite : 0;
185
+ attributes |= componentTuple.Permanent ? WindowsInstallerConstants.MsidbComponentAttributesPermanent : 0;
186
+ attributes |= componentTuple.SharedDllRefCount ? WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount : 0;
187
+ attributes |= componentTuple.Shared ? WindowsInstallerConstants.MsidbComponentAttributesShared : 0;
188
+ attributes |= componentTuple.Transitive ? WindowsInstallerConstants.MsidbComponentAttributesTransitive : 0;
189
+ attributes |= componentTuple.UninstallWhenSuperseded ? WindowsInstallerConstants.MsidbComponentAttributes64bit : 0;
190
+ attributes |= componentTuple.Win64 ? WindowsInstallerConstants.MsidbComponentAttributes64bit : 0;
191
+
192
+ fields = String.Join(",",
193
+ componentTuple.ComponentId,
194
+ componentTuple.DirectoryRef,
195
+ attributes.ToString(),
196
+ componentTuple.Condition,
197
+ componentTuple.KeyPath
198
+ );
199
+ break;
200
+ }
201
+ case "CustomAction":
202
+ {
203
+ var customActionTuple = (CustomActionTuple)tuple;
204
+ var type = customActionTuple.Win64 ? WindowsInstallerConstants.MsidbCustomActionType64BitScript : 0;
205
+ type |= customActionTuple.TSAware ? WindowsInstallerConstants.MsidbCustomActionTypeTSAware : 0;
206
+ type |= customActionTuple.Impersonate ? 0 : WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate;
207
+ type |= customActionTuple.IgnoreResult ? WindowsInstallerConstants.MsidbCustomActionTypeContinue : 0;
208
+ type |= customActionTuple.Hidden ? WindowsInstallerConstants.MsidbCustomActionTypeHideTarget : 0;
209
+ type |= customActionTuple.Async ? WindowsInstallerConstants.MsidbCustomActionTypeAsync : 0;
210
+ type |= CustomActionExecutionType.FirstSequence == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeFirstSequence : 0;
211
+ type |= CustomActionExecutionType.OncePerProcess == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeOncePerProcess : 0;
212
+ type |= CustomActionExecutionType.ClientRepeat == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeClientRepeat : 0;
213
+ type |= CustomActionExecutionType.Deferred == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript : 0;
214
+ type |= CustomActionExecutionType.Rollback == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript | WindowsInstallerConstants.MsidbCustomActionTypeRollback : 0;
215
+ type |= CustomActionExecutionType.Commit == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript | WindowsInstallerConstants.MsidbCustomActionTypeCommit : 0;
216
+ type |= CustomActionSourceType.File == customActionTuple.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeSourceFile : 0;
217
+ type |= CustomActionSourceType.Directory == customActionTuple.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeDirectory : 0;
218
+ type |= CustomActionSourceType.Property == customActionTuple.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeProperty : 0;
219
+ type |= CustomActionTargetType.Dll == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeDll : 0;
220
+ type |= CustomActionTargetType.Exe == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeExe : 0;
221
+ type |= CustomActionTargetType.TextData == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeTextData : 0;
222
+ type |= CustomActionTargetType.JScript == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeJScript : 0;
223
+ type |= CustomActionTargetType.VBScript == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeVBScript : 0;
224
+
225
+ fields = String.Join(",",
226
+ type.ToString(),
227
+ customActionTuple.Source,
228
+ customActionTuple.Target,
229
+ customActionTuple.PatchUninstall ? WindowsInstallerConstants.MsidbCustomActionTypePatchUninstall.ToString() : null
230
+ );
231
+ break;
232
+ }
233
+ case "Directory":
234
+ {
235
+ var directoryTuple = (DirectoryTuple)tuple;
236
249
- case "RemoveRegistry":
237
+ if (!String.IsNullOrEmpty(directoryTuple.ComponentGuidGenerationSeed))
238
{
251
- var removeRegistryTuple = (RemoveRegistryTuple)tuple;
252
- fields = String.Join(",",
253
- ((int)removeRegistryTuple.Root).ToString(),
254
- removeRegistryTuple.Key,
255
- removeRegistryTuple.Name,
256
- removeRegistryTuple.Component_
257
- );
258
- break;
239
+ yield return $"WixDirectory:{directoryTuple.Id.Id},{directoryTuple.ComponentGuidGenerationSeed}";
240
}
241
261
- case "ServiceControl":
262
- {
263
- var serviceControlTuple = (ServiceControlTuple)tuple;
264
-
265
- var events = serviceControlTuple.InstallRemove ? WindowsInstallerConstants.MsidbServiceControlEventDelete : 0;
266
- events |= serviceControlTuple.UninstallRemove ? WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete : 0;
267
- events |= serviceControlTuple.InstallStart ? WindowsInstallerConstants.MsidbServiceControlEventStart : 0;
268
- events |= serviceControlTuple.UninstallStart ? WindowsInstallerConstants.MsidbServiceControlEventUninstallStart : 0;
269
- events |= serviceControlTuple.InstallStop ? WindowsInstallerConstants.MsidbServiceControlEventStop : 0;
270
- events |= serviceControlTuple.UninstallStop ? WindowsInstallerConstants.MsidbServiceControlEventUninstallStop : 0;
271
-
272
- fields = String.Join(",",
273
- serviceControlTuple.Name,
274
- events.ToString(),
275
- serviceControlTuple.Arguments,
276
- serviceControlTuple.Wait == true ? "1" : "0",
277
- serviceControlTuple.Component_
278
- );
279
- break;
280
- }
242
+ fields = String.Join(",", directoryTuple.ParentDirectoryRef, directoryTuple.Name, directoryTuple.ShortName, directoryTuple.SourceName, directoryTuple.SourceShortName);
243
+ break;
244
+ }
245
+ case "Feature":
246
+ {
247
+ var featureTuple = (FeatureTuple)tuple;
248
+ var attributes = featureTuple.DisallowAbsent ? WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent : 0;
249
+ attributes |= featureTuple.DisallowAdvertise ? WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise : 0;
250
+ attributes |= FeatureInstallDefault.FollowParent == featureTuple.InstallDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFollowParent : 0;
251
+ attributes |= FeatureInstallDefault.Source == featureTuple.InstallDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFavorSource : 0;
252
+ attributes |= FeatureTypicalDefault.Advertise == featureTuple.TypicalDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise : 0;
253
+
254
+ fields = String.Join(",",
255
+ featureTuple.ParentFeatureRef,
256
+ featureTuple.Title,
257
+ featureTuple.Description,
258
+ featureTuple.Display.ToString(),
259
+ featureTuple.Level.ToString(),
260
+ featureTuple.DirectoryRef,
261
+ attributes.ToString());
262
+ break;
263
+ }
264
+ case "File":
265
+ {
266
+ var fileTuple = (FileTuple)tuple;
267
282
- case "ServiceInstall":
268
+ if (fileTuple.BindPath != null)
269
{
284
- var serviceInstallTuple = (ServiceInstallTuple)tuple;
285
-
286
- var errorControl = (int)serviceInstallTuple.ErrorControl;
287
- errorControl |= serviceInstallTuple.Vital ? WindowsInstallerConstants.MsidbServiceInstallErrorControlVital : 0;
288
-
289
- var serviceType = (int)serviceInstallTuple.ServiceType;
290
- serviceType |= serviceInstallTuple.Interactive ? WindowsInstallerConstants.MsidbServiceInstallInteractive : 0;
291
-
292
- fields = String.Join(",",
293
- serviceInstallTuple.Name,
294
- serviceInstallTuple.DisplayName,
295
- serviceType.ToString(),
296
- ((int)serviceInstallTuple.StartType).ToString(),
297
- errorControl.ToString(),
298
- serviceInstallTuple.LoadOrderGroup,
299
- serviceInstallTuple.Dependencies,
300
- serviceInstallTuple.StartName,
301
- serviceInstallTuple.Password,
302
- serviceInstallTuple.Arguments,
303
- serviceInstallTuple.Component_,
304
- serviceInstallTuple.Description
305
- );
306
- break;
270
+ yield return $"BindImage:{fileTuple.Id.Id},{fileTuple.BindPath}";
271
}
272
309
- case "Upgrade":
273
+ if (fileTuple.FontTitle != null)
274
{
311
- var upgradeTuple = (UpgradeTuple)tuple;
312
-
313
- var attributes = upgradeTuple.MigrateFeatures ? WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures : 0;
314
- attributes |= upgradeTuple.OnlyDetect ? WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect : 0;
315
- attributes |= upgradeTuple.IgnoreRemoveFailures ? WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure : 0;
316
- attributes |= upgradeTuple.VersionMinInclusive ? WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive : 0;
317
- attributes |= upgradeTuple.VersionMaxInclusive ? WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive : 0;
318
- attributes |= upgradeTuple.ExcludeLanguages ? WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive : 0;
319
-
320
- fields = String.Join(",",
321
- upgradeTuple.VersionMin,
322
- upgradeTuple.VersionMax,
323
- upgradeTuple.Language,
324
- attributes.ToString(),
325
- upgradeTuple.Remove,
326
- upgradeTuple.ActionProperty
327
- );
328
- break;
275
+ yield return $"Font:{fileTuple.Id.Id},{fileTuple.FontTitle}";
276
}
277
331
- case "WixAction":
278
+ if (fileTuple.SelfRegCost.HasValue)
279
{
333
- var wixActionTuple = (WixActionTuple)tuple;
334
- fields = String.Join(",",
335
- wixActionTuple.SequenceTable,
336
- wixActionTuple.Action,
337
- wixActionTuple.Condition,
338
- // BUGBUGBUG: AB#2626
339
- wixActionTuple.Sequence == 0 ? String.Empty : wixActionTuple.Sequence.ToString(),
340
- wixActionTuple.Before,
341
- wixActionTuple.After,
342
- wixActionTuple.Overridable == true ? "1" : "0"
343
- );
344
- break;
280
+ yield return $"SelfReg:{fileTuple.Id.Id},{fileTuple.SelfRegCost}";
281
}
282
347
- case "WixComplexReference":
348
- {
349
- var wixComplexReferenceTuple = (WixComplexReferenceTuple)tuple;
350
- fields = String.Join(",",
351
- wixComplexReferenceTuple.Parent,
352
- ((int)wixComplexReferenceTuple.ParentType).ToString(),
353
- wixComplexReferenceTuple.ParentLanguage,
354
- wixComplexReferenceTuple.Child,
355
- ((int)wixComplexReferenceTuple.ChildType).ToString(),
356
- wixComplexReferenceTuple.IsPrimary ? "1" : "0"
357
- );
358
- break;
359
- }
283
+ fields = String.Join(",",
284
+ fileTuple.ComponentRef,
285
+ fileTuple.Name,
286
+ fileTuple.FileSize.ToString(),
287
+ fileTuple.Version,
288
+ fileTuple.Language,
289
+ ((fileTuple.ReadOnly ? WindowsInstallerConstants.MsidbFileAttributesReadOnly : 0)
290
+ | (fileTuple.Hidden ? WindowsInstallerConstants.MsidbFileAttributesHidden : 0)
291
+ | (fileTuple.System ? WindowsInstallerConstants.MsidbFileAttributesSystem : 0)
292
+ | (fileTuple.Vital ? WindowsInstallerConstants.MsidbFileAttributesVital : 0)
293
+ | (fileTuple.Checksum ? WindowsInstallerConstants.MsidbFileAttributesChecksum : 0)
294
+ | ((fileTuple.Compressed.HasValue && fileTuple.Compressed.Value) ? WindowsInstallerConstants.MsidbFileAttributesCompressed : 0)
295
+ | ((fileTuple.Compressed.HasValue && !fileTuple.Compressed.Value) ? WindowsInstallerConstants.MsidbFileAttributesNoncompressed : 0))
296
+ .ToString());
297
+ break;
298
+ }
299
361
- case "WixFile":
362
- {
363
- var wixFileTuple = (WixFileTuple)tuple;
364
- fields = String.Concat(
365
- wixFileTuple.AssemblyType == FileAssemblyType.DotNetAssembly ? "0" : wixFileTuple.AssemblyType == FileAssemblyType.Win32Assembly ? "1" : String.Empty, ",",
366
- String.Join(",", tuple.Fields.Skip(2).Take(6).Select(field => (string)field).ToArray()));
367
- break;
368
- }
300
+ case "Media":
301
+ fields = String.Join(",", tuple.Fields.Skip(1).Select(SafeConvertField));
302
+ break;
303
+
304
+ case "Registry":
305
+ {
306
+ var registryTuple = (RegistryTuple)tuple;
307
+ var value = registryTuple.Value;
308
370
- case "WixProperty":
309
+ switch (registryTuple.ValueType)
310
{
372
- var wixPropertyTuple = (WixPropertyTuple)tuple;
373
- var attributes = 0;
374
- attributes |= wixPropertyTuple.Admin ? 0x1 : 0;
375
- attributes |= wixPropertyTuple.Hidden ? 0x2 : 0;
376
- attributes |= wixPropertyTuple.Secure ? 0x4 : 0;
377
-
378
- fields = String.Join(",",
379
- wixPropertyTuple.Property_,
380
- attributes.ToString()
381
- );
311
+ case RegistryValueType.Binary:
312
+ value = String.Concat("#x", value);
313
+ break;
314
+ case RegistryValueType.Expandable:
315
+ value = String.Concat("#%", value);
316
+ break;
317
+ case RegistryValueType.Integer:
318
+ value = String.Concat("#", value);
319
+ break;
320
+ case RegistryValueType.MultiString:
321
+ switch (registryTuple.ValueAction)
322
+ {
323
+ case RegistryValueActionType.Append:
324
+ value = String.Concat("[~]", value);
325
+ break;
326
+ case RegistryValueActionType.Prepend:
327
+ value = String.Concat(value, "[~]");
328
+ break;
329
+ case RegistryValueActionType.Write:
330
+ default:
331
+ if (null != value && -1 == value.IndexOf("[~]", StringComparison.Ordinal))
332
+ {
333
+ value = String.Concat("[~]", value, "[~]");
334
+ }
335
+ break;
336
+ }
337
+ break;
338
+ case RegistryValueType.String:
339
+ // escape the leading '#' character for string registry keys
340
+ if (null != value && value.StartsWith("#", StringComparison.Ordinal))
341
+ {
342
+ value = String.Concat("#", value);
343
+ }
344
break;
345
}
346
347
+ fields = String.Join(",",
348
+ ((int)registryTuple.Root).ToString(),
349
+ registryTuple.Key,
350
+ registryTuple.Name,
351
+ value,
352
+ registryTuple.ComponentRef
353
+ );
354
+ break;
355
+ }
356
+
357
+ case "RemoveRegistry":
358
+ {
359
+ var removeRegistryTuple = (RemoveRegistryTuple)tuple;
360
+ fields = String.Join(",",
361
+ ((int)removeRegistryTuple.Root).ToString(),
362
+ removeRegistryTuple.Key,
363
+ removeRegistryTuple.Name,
364
+ removeRegistryTuple.ComponentRef
365
+ );
366
+ break;
367
+ }
368
+
369
+ case "ServiceControl":
370
+ {
371
+ var serviceControlTuple = (ServiceControlTuple)tuple;
372
+
373
+ var events = serviceControlTuple.InstallRemove ? WindowsInstallerConstants.MsidbServiceControlEventDelete : 0;
374
+ events |= serviceControlTuple.UninstallRemove ? WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete : 0;
375
+ events |= serviceControlTuple.InstallStart ? WindowsInstallerConstants.MsidbServiceControlEventStart : 0;
376
+ events |= serviceControlTuple.UninstallStart ? WindowsInstallerConstants.MsidbServiceControlEventUninstallStart : 0;
377
+ events |= serviceControlTuple.InstallStop ? WindowsInstallerConstants.MsidbServiceControlEventStop : 0;
378
+ events |= serviceControlTuple.UninstallStop ? WindowsInstallerConstants.MsidbServiceControlEventUninstallStop : 0;
379
+
380
+ fields = String.Join(",",
381
+ serviceControlTuple.Name,
382
+ events.ToString(),
383
+ serviceControlTuple.Arguments,
384
+ serviceControlTuple.Wait == true ? "1" : "0",
385
+ serviceControlTuple.ComponentRef
386
+ );
387
+ break;
388
+ }
389
+
390
+ case "ServiceInstall":
391
+ {
392
+ var serviceInstallTuple = (ServiceInstallTuple)tuple;
393
+
394
+ var errorControl = (int)serviceInstallTuple.ErrorControl;
395
+ errorControl |= serviceInstallTuple.Vital ? WindowsInstallerConstants.MsidbServiceInstallErrorControlVital : 0;
396
+
397
+ var serviceType = (int)serviceInstallTuple.ServiceType;
398
+ serviceType |= serviceInstallTuple.Interactive ? WindowsInstallerConstants.MsidbServiceInstallInteractive : 0;
399
+
400
+ fields = String.Join(",",
401
+ serviceInstallTuple.Name,
402
+ serviceInstallTuple.DisplayName,
403
+ serviceType.ToString(),
404
+ ((int)serviceInstallTuple.StartType).ToString(),
405
+ errorControl.ToString(),
406
+ serviceInstallTuple.LoadOrderGroup,
407
+ serviceInstallTuple.Dependencies,
408
+ serviceInstallTuple.StartName,
409
+ serviceInstallTuple.Password,
410
+ serviceInstallTuple.Arguments,
411
+ serviceInstallTuple.ComponentRef,
412
+ serviceInstallTuple.Description
413
+ );
414
+ break;
415
+ }
416
+
417
+ case "Upgrade":
418
+ {
419
+ var upgradeTuple = (UpgradeTuple)tuple;
420
+
421
+ var attributes = upgradeTuple.MigrateFeatures ? WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures : 0;
422
+ attributes |= upgradeTuple.OnlyDetect ? WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect : 0;
423
+ attributes |= upgradeTuple.IgnoreRemoveFailures ? WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure : 0;
424
+ attributes |= upgradeTuple.VersionMinInclusive ? WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive : 0;
425
+ attributes |= upgradeTuple.VersionMaxInclusive ? WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive : 0;
426
+ attributes |= upgradeTuple.ExcludeLanguages ? WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive : 0;
427
+
428
+ fields = String.Join(",",
429
+ upgradeTuple.VersionMin,
430
+ upgradeTuple.VersionMax,
431
+ upgradeTuple.Language,
432
+ attributes.ToString(),
433
+ upgradeTuple.Remove,
434
+ upgradeTuple.ActionProperty
435
+ );
436
+ break;
437
+ }
438
+
439
+ case "WixAction":
440
+ {
441
+ var wixActionTuple = (WixActionTuple)tuple;
442
+ var data = wixActionTuple.Fields[(int)WixActionTupleFields.SequenceTable].AsObject();
443
+ var sequenceTableAsInt = data is string ? (int)SequenceStringToSequenceTable(data) : (int)wixActionTuple.SequenceTable;
444
+
445
+ fields = String.Join(",",
446
+ sequenceTableAsInt,
447
+ wixActionTuple.Action,
448
+ wixActionTuple.Condition,
449
+ wixActionTuple.Sequence?.ToString() ?? String.Empty,
450
+ wixActionTuple.Before,
451
+ wixActionTuple.After,
452
+ wixActionTuple.Overridable == true ? "1" : "0"
453
+ );
454
+ break;
455
+ }
456
+
457
+ case "WixComplexReference":
458
+ {
459
+ var wixComplexReferenceTuple = (WixComplexReferenceTuple)tuple;
460
+ fields = String.Join(",",
461
+ wixComplexReferenceTuple.Parent,
462
+ (int)wixComplexReferenceTuple.ParentType,
463
+ wixComplexReferenceTuple.ParentLanguage,
464
+ wixComplexReferenceTuple.Child,
465
+ (int)wixComplexReferenceTuple.ChildType,
466
+ wixComplexReferenceTuple.IsPrimary ? "1" : "0"
467
+ );
468
+ break;
469
+ }
470
+
471
+ case "WixFile":
472
+ {
473
+ var wixFileTuple = (WixFileTuple)tuple;
474
+ fields = String.Concat(
475
+ wixFileTuple.AssemblyType == FileAssemblyType.DotNetAssembly ? "0" : wixFileTuple.AssemblyType == FileAssemblyType.Win32Assembly ? "1" : String.Empty, ",",
476
+ String.Join(",", tuple.Fields.Skip(1).Take(8).Select(field => (string)field)));
477
+ break;
478
+ }
479
+
480
+ case "WixProperty":
481
+ {
482
+ var wixPropertyTuple = (WixPropertyTuple)tuple;
483
+ var attributes = wixPropertyTuple.Admin ? 0x1 : 0;
484
+ attributes |= wixPropertyTuple.Hidden ? 0x2 : 0;
485
+ attributes |= wixPropertyTuple.Secure ? 0x4 : 0;
486
+
487
+ fields = String.Join(",",
488
+ wixPropertyTuple.PropertyRef,
489
+ attributes.ToString()
490
+ );
491
+ break;
492
+ }
493
+
494
+ default:
495
+ fields = String.Join(",", tuple.Fields.Select(SafeConvertField));
496
+ break;
497
+ }
498
+
499
+ var name = tuple.Definition.Type == TupleDefinitionType.SummaryInformation ? "_SummaryInformation" : tuple.Definition.Name;
500
+ var id = tuple.Id?.Id ?? String.Empty;
501
+ fields = String.IsNullOrEmpty(id) ? fields : String.IsNullOrEmpty(fields) ? id : $"{id},{fields}";
502
+ yield return $"{name}:{fields}";
503
+ }
504
+
505
+ private static SequenceTable SequenceStringToSequenceTable(object sequenceString)
506
+ {
507
+ switch (sequenceString)
508
+ {
509
+ case "AdminExecuteSequence":
510
+ return SequenceTable.AdminExecuteSequence;
511
+ case "AdminUISequence":
512
+ return SequenceTable.AdminUISequence;
513
+ case "AdvtExecuteSequence":
514
+ return SequenceTable.AdvertiseExecuteSequence;
515
+ case "InstallExecuteSequence":
516
+ return SequenceTable.InstallExecuteSequence;
517
+ case "InstallUISequence":
518
+ return SequenceTable.InstallUISequence;
519
+ default:
520
+ throw new ArgumentException($"Unknown sequence: {sequenceString}");
521
}
522
+ }
523
387
- var id = tuple.Id == null ? String.Empty : String.Concat(",", tuple.Id.Id);
388
- return $"{tuple.Definition.Name}{id},{fields}";
524
+ private static string SafeConvertField(Wix3.Field field)
525
+ {
526
+ return field?.Data?.ToString();
527
+ }
528
+
529
+ private static string SafeConvertField(IntermediateField field)
530
+ {
531
+ var data = field.AsObject();
532
+ if (data is IntermediateFieldPathValue path)
533
+ {
534
+ return path.Path;
535
+ }
536
+
537
+ return data?.ToString();
538
+ }
539
+
540
+ private static string[] SplitDefaultDir(string defaultDir)
541
+ {
542
+ var split1 = defaultDir.Split(':');
543
+ var targetSplit = split1.Length > 1 ? split1[1].Split('|') : split1[0].Split('|');
544
+ var sourceSplit = split1.Length > 1 ? split1[0].Split('|') : new[] { String.Empty };
545
+ return new[]
546
+ {
547
+ targetSplit.Length > 1 ? targetSplit[1] : targetSplit[0],
548
+ targetSplit.Length > 1 ? targetSplit[0] : String.Empty,
549
+ sourceSplit.Length > 1 ? sourceSplit[1] : sourceSplit[0],
550
+ sourceSplit.Length > 1 ? sourceSplit[0] : String.Empty
551
+ };
552
}
553
}
554
}