diff options
author | Rob Mensching <rob@firegiant.com> | 2019-05-22 00:54:09 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2019-05-23 16:07:04 -0700 |
commit | b645ddc2c1386c1199ca1e7790201d7a5ab6627b (patch) | |
tree | a814a22337e2350b8ae26d74d806af4da2ed4e0f /src | |
parent | 6f6c485118796f044a278447722eaf18ac5bf86e (diff) | |
download | wix-b645ddc2c1386c1199ca1e7790201d7a5ab6627b.tar.gz wix-b645ddc2c1386c1199ca1e7790201d7a5ab6627b.tar.bz2 wix-b645ddc2c1386c1199ca1e7790201d7a5ab6627b.zip |
Integrate latest changes to tuple definitions
Diffstat (limited to 'src')
-rw-r--r-- | src/WixToolset.Converters.Tupleizer/ConvertTuplesCommand.cs | 928 | ||||
-rw-r--r-- | src/test/WixToolsetTest.Converters.Tupleizer/ConvertTuplesFixture.cs | 747 |
2 files changed, 1020 insertions, 655 deletions
diff --git a/src/WixToolset.Converters.Tupleizer/ConvertTuplesCommand.cs b/src/WixToolset.Converters.Tupleizer/ConvertTuplesCommand.cs index c07dd42e..007b9c62 100644 --- a/src/WixToolset.Converters.Tupleizer/ConvertTuplesCommand.cs +++ b/src/WixToolset.Converters.Tupleizer/ConvertTuplesCommand.cs | |||
@@ -3,6 +3,7 @@ | |||
3 | namespace WixToolset.Converters.Tupleizer | 3 | namespace WixToolset.Converters.Tupleizer |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections.Generic; | ||
6 | using System.Linq; | 7 | using System.Linq; |
7 | using WixToolset.Data; | 8 | using WixToolset.Data; |
8 | using WixToolset.Data.Tuples; | 9 | using WixToolset.Data.Tuples; |
@@ -21,11 +22,17 @@ namespace WixToolset.Converters.Tupleizer | |||
21 | { | 22 | { |
22 | var section = new IntermediateSection(String.Empty, OutputType3ToSectionType4(output.Type), output.Codepage); | 23 | var section = new IntermediateSection(String.Empty, OutputType3ToSectionType4(output.Type), output.Codepage); |
23 | 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 | |||
24 | foreach (Wix3.Table table in output.Tables) | 31 | foreach (Wix3.Table table in output.Tables) |
25 | { | 32 | { |
26 | foreach (Wix3.Row row in table.Rows) | 33 | foreach (Wix3.Row row in table.Rows) |
27 | { | 34 | { |
28 | var tuple = GenerateTupleFromRow(row); | 35 | var tuple = GenerateTupleFromRow(row, wixMediaByDiskId, fontsById, bindPathsById, selfRegById, wixDirectoryById); |
29 | if (tuple != null) | 36 | if (tuple != null) |
30 | { | 37 | { |
31 | section.Tuples.Add(tuple); | 38 | section.Tuples.Add(tuple); |
@@ -36,353 +43,534 @@ namespace WixToolset.Converters.Tupleizer | |||
36 | return new Intermediate(String.Empty, new[] { section }, localizationsByCulture: null, embedFilePaths: null); | 43 | return new Intermediate(String.Empty, new[] { section }, localizationsByCulture: null, embedFilePaths: null); |
37 | } | 44 | } |
38 | 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) | ||
40 | { | 79 | { |
41 | var name = row.Table.Name; | 80 | var name = row.Table.Name; |
42 | switch (name) | 81 | switch (name) |
43 | { | 82 | { |
44 | case "_SummaryInformation": | 83 | case "_SummaryInformation": |
45 | return DefaultTupleFromRow(typeof(_SummaryInformationTuple), row, columnZeroIsId: false); | 84 | return DefaultTupleFromRow(typeof(SummaryInformationTuple), row, columnZeroIsId: false); |
46 | case "ActionText": | 85 | case "ActionText": |
47 | return DefaultTupleFromRow(typeof(ActionTextTuple), row, columnZeroIsId: false); | 86 | return DefaultTupleFromRow(typeof(ActionTextTuple), row, columnZeroIsId: false); |
48 | case "AdvtExecuteSequence": | 87 | case "AdvtExecuteSequence": |
49 | return DefaultTupleFromRow(typeof(AdvtExecuteSequenceTuple), row, columnZeroIsId: false); | 88 | return DefaultTupleFromRow(typeof(AdvtExecuteSequenceTuple), row, columnZeroIsId: false); |
50 | case "AppId": | 89 | case "AppId": |
51 | return DefaultTupleFromRow(typeof(AppIdTuple), row, columnZeroIsId: false); | 90 | return DefaultTupleFromRow(typeof(AppIdTuple), row, columnZeroIsId: false); |
52 | case "AppSearch": | 91 | case "AppSearch": |
53 | return DefaultTupleFromRow(typeof(AppSearchTuple), row, columnZeroIsId: false); | 92 | return DefaultTupleFromRow(typeof(AppSearchTuple), row, columnZeroIsId: false); |
54 | case "Binary": | 93 | case "Billboard": |
55 | return DefaultTupleFromRow(typeof(BinaryTuple), row, columnZeroIsId: false); | 94 | return DefaultTupleFromRow(typeof(BillboardTuple), row, columnZeroIsId: true); |
56 | case "Class": | 95 | case "Binary": |
57 | return DefaultTupleFromRow(typeof(ClassTuple), row, columnZeroIsId: false); | 96 | return DefaultTupleFromRow(typeof(BinaryTuple), row, columnZeroIsId: true); |
58 | case "CompLocator": | 97 | case "BindPath": |
59 | return DefaultTupleFromRow(typeof(CompLocatorTuple), row, columnZeroIsId: true); | 98 | return null; |
60 | case "Component": | 99 | case "CCPSearch": |
61 | { | 100 | return DefaultTupleFromRow(typeof(CCPSearchTuple), row, columnZeroIsId: true); |
62 | var attributes = FieldAsNullableInt(row, 3); | 101 | case "Class": |
63 | 102 | return DefaultTupleFromRow(typeof(ClassTuple), row, columnZeroIsId: false); | |
64 | var location = ComponentLocation.LocalOnly; | 103 | case "CompLocator": |
65 | if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesSourceOnly) == WindowsInstallerConstants.MsidbComponentAttributesSourceOnly) | 104 | return DefaultTupleFromRow(typeof(CompLocatorTuple), row, columnZeroIsId: true); |
66 | { | 105 | case "Component": |
67 | location = ComponentLocation.SourceOnly; | 106 | { |
68 | } | 107 | var attributes = FieldAsNullableInt(row, 3); |
69 | else if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesOptional) == WindowsInstallerConstants.MsidbComponentAttributesOptional) | ||
70 | { | ||
71 | location = ComponentLocation.Either; | ||
72 | } | ||
73 | 108 | ||
74 | var keyPathType = ComponentKeyPathType.File; | 109 | var location = ComponentLocation.LocalOnly; |
75 | if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath) == WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath) | 110 | if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesSourceOnly) == WindowsInstallerConstants.MsidbComponentAttributesSourceOnly) |
76 | { | 111 | { |
77 | keyPathType = ComponentKeyPathType.Registry; | 112 | location = ComponentLocation.SourceOnly; |
78 | } | 113 | } |
79 | else if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource) == WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource) | 114 | else if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesOptional) == WindowsInstallerConstants.MsidbComponentAttributesOptional) |
80 | { | 115 | { |
81 | keyPathType = ComponentKeyPathType.OdbcDataSource; | 116 | location = ComponentLocation.Either; |
82 | } | 117 | } |
83 | 118 | ||
84 | return new ComponentTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) | 119 | var keyPathType = ComponentKeyPathType.File; |
85 | { | 120 | if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath) == WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath) |
86 | ComponentId = FieldAsString(row, 1), | 121 | { |
87 | Directory_ = FieldAsString(row, 2), | 122 | keyPathType = ComponentKeyPathType.Registry; |
88 | Condition = FieldAsString(row, 4), | 123 | } |
89 | KeyPath = FieldAsString(row, 5), | 124 | else if ((attributes & WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource) == WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource) |
90 | Location = location, | 125 | { |
91 | DisableRegistryReflection = (attributes & WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection) == WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection, | 126 | keyPathType = ComponentKeyPathType.OdbcDataSource; |
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 | }; | ||
101 | } | 127 | } |
102 | 128 | ||
103 | case "Condition": | 129 | return new ComponentTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) |
104 | return DefaultTupleFromRow(typeof(ConditionTuple), row, columnZeroIsId: false); | ||
105 | case "CreateFolder": | ||
106 | return DefaultTupleFromRow(typeof(CreateFolderTuple), row, columnZeroIsId: false); | ||
107 | case "CustomAction": | ||
108 | { | 130 | { |
109 | var caType = FieldAsInt(row, 1); | 131 | ComponentId = FieldAsString(row, 1), |
110 | var executionType = DetermineCustomActionExecutionType(caType); | 132 | DirectoryRef = FieldAsString(row, 2), |
111 | var sourceType = DetermineCustomActionSourceType(caType); | 133 | Condition = FieldAsString(row, 4), |
112 | var targetType = DetermineCustomActionTargetType(caType); | 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 | } | ||
113 | 147 | ||
114 | return new CustomActionTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) | 148 | case "Condition": |
115 | { | 149 | return DefaultTupleFromRow(typeof(ConditionTuple), row, columnZeroIsId: false); |
116 | ExecutionType = executionType, | 150 | case "CreateFolder": |
117 | SourceType = sourceType, | 151 | return DefaultTupleFromRow(typeof(CreateFolderTuple), row, columnZeroIsId: false); |
118 | Source = FieldAsString(row, 2), | 152 | case "CustomAction": |
119 | TargetType = targetType, | 153 | { |
120 | Target = FieldAsString(row, 3), | 154 | var caType = FieldAsInt(row, 1); |
121 | Win64 = (caType & WindowsInstallerConstants.MsidbCustomActionType64BitScript) == WindowsInstallerConstants.MsidbCustomActionType64BitScript, | 155 | var executionType = DetermineCustomActionExecutionType(caType); |
122 | TSAware = (caType & WindowsInstallerConstants.MsidbCustomActionTypeTSAware) == WindowsInstallerConstants.MsidbCustomActionTypeTSAware, | 156 | var sourceType = DetermineCustomActionSourceType(caType); |
123 | Impersonate = (caType & WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate) != WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate, | 157 | var targetType = DetermineCustomActionTargetType(caType); |
124 | IgnoreResult = (caType & WindowsInstallerConstants.MsidbCustomActionTypeContinue) == WindowsInstallerConstants.MsidbCustomActionTypeContinue, | ||
125 | Hidden = (caType & WindowsInstallerConstants.MsidbCustomActionTypeHideTarget) == WindowsInstallerConstants.MsidbCustomActionTypeHideTarget, | ||
126 | Async = (caType & WindowsInstallerConstants.MsidbCustomActionTypeAsync) == WindowsInstallerConstants.MsidbCustomActionTypeAsync, | ||
127 | }; | ||
128 | } | ||
129 | 158 | ||
130 | case "Directory": | 159 | return new CustomActionTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) |
131 | return DefaultTupleFromRow(typeof(DirectoryTuple), row, columnZeroIsId: false); | 160 | { |
132 | case "DrLocator": | 161 | ExecutionType = executionType, |
133 | return DefaultTupleFromRow(typeof(DrLocatorTuple), row, columnZeroIsId: false); | 162 | SourceType = sourceType, |
134 | case "Error": | 163 | Source = FieldAsString(row, 2), |
135 | return DefaultTupleFromRow(typeof(ErrorTuple), row, columnZeroIsId: false); | 164 | TargetType = targetType, |
136 | case "Extension": | 165 | Target = FieldAsString(row, 3), |
137 | return DefaultTupleFromRow(typeof(ExtensionTuple), row, columnZeroIsId: false); | 166 | Win64 = (caType & WindowsInstallerConstants.MsidbCustomActionType64BitScript) == WindowsInstallerConstants.MsidbCustomActionType64BitScript, |
138 | case "Feature": | 167 | TSAware = (caType & WindowsInstallerConstants.MsidbCustomActionTypeTSAware) == WindowsInstallerConstants.MsidbCustomActionTypeTSAware, |
139 | { | 168 | Impersonate = (caType & WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate) != WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate, |
140 | int attributes = FieldAsInt(row, 7); | 169 | IgnoreResult = (caType & WindowsInstallerConstants.MsidbCustomActionTypeContinue) == WindowsInstallerConstants.MsidbCustomActionTypeContinue, |
141 | var installDefault = FeatureInstallDefault.Local; | 170 | Hidden = (caType & WindowsInstallerConstants.MsidbCustomActionTypeHideTarget) == WindowsInstallerConstants.MsidbCustomActionTypeHideTarget, |
142 | if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFollowParent) == WindowsInstallerConstants.MsidbFeatureAttributesFollowParent) | 171 | Async = (caType & WindowsInstallerConstants.MsidbCustomActionTypeAsync) == WindowsInstallerConstants.MsidbCustomActionTypeAsync, |
143 | { | 172 | }; |
144 | installDefault = FeatureInstallDefault.FollowParent; | 173 | } |
145 | } | ||
146 | else | ||
147 | if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorSource) == WindowsInstallerConstants.MsidbFeatureAttributesFavorSource) | ||
148 | { | ||
149 | installDefault = FeatureInstallDefault.Source; | ||
150 | } | ||
151 | 174 | ||
152 | return new FeatureTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) | 175 | case "Directory": |
153 | { | 176 | { |
154 | Feature_Parent = FieldAsString(row, 1), | 177 | var id = FieldAsString(row, 0); |
155 | Title = FieldAsString(row, 2), | 178 | var splits = SplitDefaultDir(FieldAsString(row, 2)); |
156 | Description = FieldAsString(row, 3), | 179 | |
157 | Display = FieldAsInt(row, 4), // BUGBUGBUG: FieldAsNullableInt(row, 4), | 180 | var tuple = new DirectoryTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, id)) |
158 | Level = FieldAsInt(row, 5), | 181 | { |
159 | Directory_ = FieldAsString(row, 6), | 182 | ParentDirectoryRef = FieldAsString(row, 1), |
160 | DisallowAbsent = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent) == WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent, | 183 | Name = splits[0], |
161 | DisallowAdvertise = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise, | 184 | ShortName = splits[1], |
162 | InstallDefault = installDefault, | 185 | SourceName = splits[2], |
163 | TypicalDefault = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise ? FeatureTypicalDefault.Advertise : FeatureTypicalDefault.Install, | 186 | SourceShortName = splits[3] |
164 | }; | 187 | }; |
188 | |||
189 | if (wixDirectoryById.TryGetValue(id, out var wixDirectoryRow)) | ||
190 | { | ||
191 | tuple.ComponentGuidGenerationSeed = FieldAsString(wixDirectoryRow, 1); | ||
165 | } | 192 | } |
166 | 193 | ||
167 | case "FeatureComponents": | 194 | return tuple; |
168 | return DefaultTupleFromRow(typeof(FeatureComponentsTuple), row, columnZeroIsId: false); | 195 | } |
169 | case "File": | 196 | case "DrLocator": |
170 | { | 197 | return DefaultTupleFromRow(typeof(DrLocatorTuple), row, columnZeroIsId: false); |
171 | var attributes = FieldAsNullableInt(row, 6); | 198 | case "DuplicateFile": |
172 | var readOnly = (attributes & WindowsInstallerConstants.MsidbFileAttributesReadOnly) == WindowsInstallerConstants.MsidbFileAttributesReadOnly; | 199 | return DefaultTupleFromRow(typeof(DuplicateFileTuple), row, columnZeroIsId: true); |
173 | var hidden = (attributes & WindowsInstallerConstants.MsidbFileAttributesHidden) == WindowsInstallerConstants.MsidbFileAttributesHidden; | 200 | case "Error": |
174 | var system = (attributes & WindowsInstallerConstants.MsidbFileAttributesSystem) == WindowsInstallerConstants.MsidbFileAttributesSystem; | 201 | return DefaultTupleFromRow(typeof(ErrorTuple), row, columnZeroIsId: false); |
175 | var vital = (attributes & WindowsInstallerConstants.MsidbFileAttributesVital) == WindowsInstallerConstants.MsidbFileAttributesVital; | 202 | case "Extension": |
176 | var checksum = (attributes & WindowsInstallerConstants.MsidbFileAttributesChecksum) == WindowsInstallerConstants.MsidbFileAttributesChecksum; | 203 | return DefaultTupleFromRow(typeof(ExtensionTuple), row, columnZeroIsId: false); |
177 | bool? compressed = null; | 204 | case "Feature": |
178 | if ((attributes & WindowsInstallerConstants.MsidbFileAttributesNoncompressed) == WindowsInstallerConstants.MsidbFileAttributesNoncompressed) | 205 | { |
179 | { | 206 | var attributes = FieldAsInt(row, 7); |
180 | compressed = false; | 207 | var installDefault = FeatureInstallDefault.Local; |
181 | } | 208 | if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFollowParent) == WindowsInstallerConstants.MsidbFeatureAttributesFollowParent) |
182 | else if ((attributes & WindowsInstallerConstants.MsidbFileAttributesCompressed) == WindowsInstallerConstants.MsidbFileAttributesCompressed) | 209 | { |
183 | { | 210 | installDefault = FeatureInstallDefault.FollowParent; |
184 | compressed = true; | 211 | } |
185 | } | 212 | else if ((attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorSource) == WindowsInstallerConstants.MsidbFeatureAttributesFavorSource) |
213 | { | ||
214 | installDefault = FeatureInstallDefault.Source; | ||
215 | } | ||
186 | 216 | ||
187 | return new FileTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) | 217 | return new FeatureTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) |
188 | { | 218 | { |
189 | Component_ = FieldAsString(row, 1), | 219 | ParentFeatureRef = FieldAsString(row, 1), |
190 | LongFileName = FieldAsString(row, 2), | 220 | Title = FieldAsString(row, 2), |
191 | FileSize = FieldAsInt(row, 3), | 221 | Description = FieldAsString(row, 3), |
192 | Version = FieldAsString(row, 4), | 222 | Display = FieldAsInt(row, 4), // BUGBUGBUG: FieldAsNullableInt(row, 4), |
193 | Language = FieldAsString(row, 5), | 223 | Level = FieldAsInt(row, 5), |
194 | ReadOnly = readOnly, | 224 | DirectoryRef = FieldAsString(row, 6), |
195 | Hidden = hidden, | 225 | DisallowAbsent = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent) == WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent, |
196 | System = system, | 226 | DisallowAdvertise = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise, |
197 | Vital = vital, | 227 | InstallDefault = installDefault, |
198 | Checksum = checksum, | 228 | TypicalDefault = (attributes & WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise) == WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise ? FeatureTypicalDefault.Advertise : FeatureTypicalDefault.Install, |
199 | Compressed = compressed, | 229 | }; |
200 | }; | 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; | ||
201 | } | 250 | } |
202 | 251 | ||
203 | case "Font": | 252 | var id = FieldAsString(row, 0); |
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 | } | ||
269 | 253 | ||
270 | return new RegistryTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) | 254 | var tuple = new FileTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, id)) |
271 | { | 255 | { |
272 | Root = (RegistryRootType)FieldAsInt(row, 1), | 256 | ComponentRef = FieldAsString(row, 1), |
273 | Key = FieldAsString(row, 2), | 257 | Name = FieldAsString(row, 2), |
274 | Name = FieldAsString(row, 3), | 258 | FileSize = FieldAsInt(row, 3), |
275 | Value = value, | 259 | Version = FieldAsString(row, 4), |
276 | Component_ = FieldAsString(row, 5), | 260 | Language = FieldAsString(row, 5), |
277 | ValueAction = valueAction, | 261 | ReadOnly = readOnly, |
278 | ValueType = valueType, | 262 | Hidden = hidden, |
279 | }; | 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; | ||
280 | } | 272 | } |
281 | 273 | ||
282 | case "RegLocator": | 274 | if (fontsById.TryGetValue(id, out var fontRow)) |
283 | return DefaultTupleFromRow(typeof(RegLocatorTuple), row, columnZeroIsId: false); | ||
284 | case "RemoveFile": | ||
285 | return DefaultTupleFromRow(typeof(RemoveFileTuple), row, columnZeroIsId: false); | ||
286 | case "RemoveRegistry": | ||
287 | { | 275 | { |
288 | return new RemoveRegistryTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) | 276 | tuple.FontTitle = FieldAsString(fontRow, 1) ?? String.Empty; |
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 | }; | ||
296 | } | 277 | } |
297 | 278 | ||
298 | case "ReserveCost": | 279 | if (selfRegById.TryGetValue(id, out var selfRegRow)) |
299 | return DefaultTupleFromRow(typeof(ReserveCostTuple), row, columnZeroIsId: false); | ||
300 | case "ServiceControl": | ||
301 | { | 280 | { |
302 | var events = FieldAsInt(row, 2); | 281 | tuple.SelfRegCost = FieldAsNullableInt(selfRegRow, 1) ?? 0; |
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 | }; | ||
317 | } | 282 | } |
318 | 283 | ||
319 | case "ServiceInstall": | 284 | return tuple; |
320 | return DefaultTupleFromRow(typeof(ServiceInstallTuple), row, columnZeroIsId: true); | 285 | } |
321 | case "Shortcut": | 286 | case "Font": |
322 | return DefaultTupleFromRow(typeof(ShortcutTuple), row, columnZeroIsId: true); | 287 | return null; |
323 | case "Signature": | 288 | case "Icon": |
324 | return DefaultTupleFromRow(typeof(SignatureTuple), row, columnZeroIsId: false); | 289 | return DefaultTupleFromRow(typeof(IconTuple), row, columnZeroIsId: true); |
325 | case "Upgrade": | 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)) | ||
326 | { | 298 | { |
327 | var attributes = FieldAsInt(row, 4); | 299 | DiskId = diskId, |
328 | return new UpgradeTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) | 300 | LastSequence = FieldAsNullableInt(row, 1), |
329 | { | 301 | DiskPrompt = FieldAsString(row, 2), |
330 | UpgradeCode = FieldAsString(row, 0), | 302 | Cabinet = FieldAsString(row, 3), |
331 | VersionMin = FieldAsString(row, 1), | 303 | VolumeLabel = FieldAsString(row, 4), |
332 | VersionMax = FieldAsString(row, 2), | 304 | Source = FieldAsString(row, 5) |
333 | Language = FieldAsString(row, 3), | 305 | }; |
334 | Remove = FieldAsString(row, 5), | 306 | |
335 | ActionProperty = FieldAsString(row, 6), | 307 | if (wixMediaByDiskId.TryGetValue(diskId, out var wixMediaRow)) |
336 | MigrateFeatures = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures) == WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures, | 308 | { |
337 | OnlyDetect = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect) == WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect, | 309 | var compressionLevel = FieldAsString(wixMediaRow, 1); |
338 | IgnoreRemoveFailures = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure) == WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure, | 310 | |
339 | VersionMinInclusive = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive, | 311 | tuple.CompressionLevel = String.IsNullOrEmpty(compressionLevel) ? null : (CompressionLevel?)Enum.Parse(typeof(CompressionLevel), compressionLevel, true); |
340 | VersionMaxInclusive = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive, | 312 | tuple.Layout = wixMediaRow.Layout; |
341 | ExcludeLanguages = (attributes & WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive, | ||
342 | }; | ||
343 | } | 313 | } |
344 | 314 | ||
345 | case "Verb": | 315 | return tuple; |
346 | return DefaultTupleFromRow(typeof(VerbTuple), row, columnZeroIsId: false); | 316 | } |
347 | //case "WixAction": | 317 | case "MIME": |
348 | // return new WixActionTuple(SourceLineNumber4(row.SourceLineNumbers)) | 318 | return DefaultTupleFromRow(typeof(MIMETuple), row, columnZeroIsId: false); |
349 | // { | 319 | case "ModuleIgnoreTable": |
350 | // SequenceTable = (SequenceTable)Enum.Parse(typeof(SequenceTable), FieldAsString(row, 0)), | 320 | return DefaultTupleFromRow(typeof(ModuleIgnoreTableTuple), row, columnZeroIsId: true); |
351 | // Action = FieldAsString(row, 1), | 321 | case "MoveFile": |
352 | // Condition = FieldAsString(row, 2), | 322 | return DefaultTupleFromRow(typeof(MoveFileTuple), row, columnZeroIsId: true); |
353 | // Sequence = FieldAsInt(row, 3), | 323 | case "MsiAssembly": |
354 | // Before = FieldAsString(row, 4), | 324 | return DefaultTupleFromRow(typeof(MsiAssemblyTuple), row, columnZeroIsId: false); |
355 | // After = FieldAsString(row, 5), | 325 | case "MsiLockPermissionsEx": |
356 | // Overridable = FieldAsNullableInt(row, 6) != 0, | 326 | return DefaultTupleFromRow(typeof(MsiLockPermissionsExTuple), row, columnZeroIsId: true); |
357 | // }; | 327 | case "MsiShortcutProperty": |
358 | case "WixFile": | 328 | return DefaultTupleFromRow(typeof(MsiShortcutPropertyTuple), row, columnZeroIsId: true); |
359 | var assemblyAttributes3 = FieldAsNullableInt(row, 1); | 329 | case "ODBCDataSource": |
360 | return new WixFileTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) | 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)) | ||
361 | { | 350 | { |
362 | AssemblyType = assemblyAttributes3 == 0 ? FileAssemblyType.DotNetAssembly : assemblyAttributes3 == 1 ? FileAssemblyType.Win32Assembly : FileAssemblyType.NotAnAssembly, | 351 | valueType = RegistryValueType.Binary; |
363 | File_AssemblyManifest = FieldAsString(row, 2), | 352 | value = value.Substring(2); |
364 | File_AssemblyApplication = FieldAsString(row, 3), | 353 | } |
365 | Directory_ = FieldAsString(row, 4), | 354 | else if (value.StartsWith("#%", StringComparison.Ordinal)) |
366 | DiskId = FieldAsInt(row, 5), // TODO: BUGBUGBUG: AB#2626: DiskId is nullable in WiX v3. | 355 | { |
367 | Source = new IntermediateFieldPathValue() { Path = FieldAsString(row, 6) }, | 356 | valueType = RegistryValueType.Expandable; |
368 | ProcessorArchitecture = FieldAsString(row, 7), | 357 | value = value.Substring(2); |
369 | PatchGroup = FieldAsInt(row, 8), | 358 | } |
370 | Attributes = FieldAsInt(row, 9), | 359 | else if (value.StartsWith("#", StringComparison.Ordinal)) |
371 | }; | 360 | { |
372 | case "WixProperty": | 361 | valueType = RegistryValueType.Integer; |
373 | { | 362 | value = value.Substring(1); |
374 | var attributes = FieldAsInt(row, 1); | 363 | } |
375 | return new WixPropertyTuple(SourceLineNumber4(row.SourceLineNumbers)) | 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)) | ||
376 | { | 377 | { |
377 | Property_ = FieldAsString(row, 0), | 378 | value = value.Substring(0, value.Length - 3); |
378 | Admin = (attributes & 0x1) == 0x1, | 379 | valueType = RegistryValueType.MultiString; |
379 | Hidden = (attributes & 0x2) == 0x2, | 380 | valueAction = RegistryValueActionType.Prepend; |
380 | Secure = (attributes & 0x4) == 0x4, | 381 | } |
381 | }; | ||
382 | } | 382 | } |
383 | 383 | ||
384 | default: | 384 | return new RegistryTuple(SourceLineNumber4(row.SourceLineNumbers), new Identifier(AccessModifier.Public, FieldAsString(row, 0))) |
385 | return GenericTupleFromCustomRow(row, columnZeroIsId: false); | 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); | ||
386 | } | 574 | } |
387 | } | 575 | } |
388 | 576 | ||
@@ -470,16 +658,16 @@ namespace WixToolset.Converters.Tupleizer | |||
470 | { | 658 | { |
471 | switch (columnType) | 659 | switch (columnType) |
472 | { | 660 | { |
473 | case Wix3.ColumnType.Number: | 661 | case Wix3.ColumnType.Number: |
474 | return IntermediateFieldType.Number; | 662 | return IntermediateFieldType.Number; |
475 | case Wix3.ColumnType.Object: | 663 | case Wix3.ColumnType.Object: |
476 | return IntermediateFieldType.Path; | 664 | return IntermediateFieldType.Path; |
477 | case Wix3.ColumnType.Unknown: | 665 | case Wix3.ColumnType.Unknown: |
478 | case Wix3.ColumnType.String: | 666 | case Wix3.ColumnType.String: |
479 | case Wix3.ColumnType.Localized: | 667 | case Wix3.ColumnType.Localized: |
480 | case Wix3.ColumnType.Preserved: | 668 | case Wix3.ColumnType.Preserved: |
481 | default: | 669 | default: |
482 | return IntermediateFieldType.String; | 670 | return IntermediateFieldType.String; |
483 | } | 671 | } |
484 | } | 672 | } |
485 | 673 | ||
@@ -520,22 +708,22 @@ namespace WixToolset.Converters.Tupleizer | |||
520 | var column = row.Fields[i].Column; | 708 | var column = row.Fields[i].Column; |
521 | switch (column.Type) | 709 | switch (column.Type) |
522 | { | 710 | { |
523 | case Wix3.ColumnType.String: | 711 | case Wix3.ColumnType.String: |
524 | case Wix3.ColumnType.Localized: | 712 | case Wix3.ColumnType.Localized: |
525 | case Wix3.ColumnType.Object: | 713 | case Wix3.ColumnType.Object: |
526 | case Wix3.ColumnType.Preserved: | 714 | case Wix3.ColumnType.Preserved: |
527 | tuple.Set(i - offset, FieldAsString(row, i)); | 715 | tuple.Set(i - offset, FieldAsString(row, i)); |
528 | break; | 716 | break; |
529 | case Wix3.ColumnType.Number: | 717 | case Wix3.ColumnType.Number: |
530 | int? nullableValue = FieldAsNullableInt(row, i); | 718 | int? nullableValue = FieldAsNullableInt(row, i); |
531 | // TODO: Consider whether null values should be coerced to their default value when | 719 | // 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. | 720 | // a column is not nullable. For now, just pass through the null. |
533 | //int value = FieldAsInt(row, i); | 721 | //int value = FieldAsInt(row, i); |
534 | //tuple.Set(i - offset, column.IsNullable ? nullableValue : value); | 722 | //tuple.Set(i - offset, column.IsNullable ? nullableValue : value); |
535 | tuple.Set(i - offset, nullableValue); | 723 | tuple.Set(i - offset, nullableValue); |
724 | break; | ||
725 | case Wix3.ColumnType.Unknown: | ||
536 | break; | 726 | break; |
537 | case Wix3.ColumnType.Unknown: | ||
538 | break; | ||
539 | } | 727 | } |
540 | } | 728 | } |
541 | } | 729 | } |
@@ -545,15 +733,15 @@ namespace WixToolset.Converters.Tupleizer | |||
545 | var column = row.Fields[0].Column; | 733 | var column = row.Fields[0].Column; |
546 | switch (column.Type) | 734 | switch (column.Type) |
547 | { | 735 | { |
548 | case Wix3.ColumnType.String: | 736 | case Wix3.ColumnType.String: |
549 | case Wix3.ColumnType.Localized: | 737 | case Wix3.ColumnType.Localized: |
550 | case Wix3.ColumnType.Object: | 738 | case Wix3.ColumnType.Object: |
551 | case Wix3.ColumnType.Preserved: | 739 | case Wix3.ColumnType.Preserved: |
552 | return new Identifier(AccessModifier.Public, (string)row.Fields[0].Data); | 740 | return new Identifier(AccessModifier.Public, (string)row.Fields[0].Data); |
553 | case Wix3.ColumnType.Number: | 741 | case Wix3.ColumnType.Number: |
554 | return new Identifier(AccessModifier.Public, FieldAsInt(row, 0)); | 742 | return new Identifier(AccessModifier.Public, FieldAsInt(row, 0)); |
555 | default: | 743 | default: |
556 | return null; | 744 | return null; |
557 | } | 745 | } |
558 | } | 746 | } |
559 | 747 | ||
@@ -561,20 +749,20 @@ namespace WixToolset.Converters.Tupleizer | |||
561 | { | 749 | { |
562 | switch (outputType) | 750 | switch (outputType) |
563 | { | 751 | { |
564 | case Wix3.OutputType.Bundle: | 752 | case Wix3.OutputType.Bundle: |
565 | return SectionType.Bundle; | 753 | return SectionType.Bundle; |
566 | case Wix3.OutputType.Module: | 754 | case Wix3.OutputType.Module: |
567 | return SectionType.Module; | 755 | return SectionType.Module; |
568 | case Wix3.OutputType.Patch: | 756 | case Wix3.OutputType.Patch: |
569 | return SectionType.Patch; | 757 | return SectionType.Patch; |
570 | case Wix3.OutputType.PatchCreation: | 758 | case Wix3.OutputType.PatchCreation: |
571 | return SectionType.PatchCreation; | 759 | return SectionType.PatchCreation; |
572 | case Wix3.OutputType.Product: | 760 | case Wix3.OutputType.Product: |
573 | return SectionType.Product; | 761 | return SectionType.Product; |
574 | case Wix3.OutputType.Transform: | 762 | case Wix3.OutputType.Transform: |
575 | case Wix3.OutputType.Unknown: | 763 | case Wix3.OutputType.Unknown: |
576 | default: | 764 | default: |
577 | return SectionType.Unknown; | 765 | return SectionType.Unknown; |
578 | } | 766 | } |
579 | } | 767 | } |
580 | 768 | ||
@@ -605,5 +793,19 @@ namespace WixToolset.Converters.Tupleizer | |||
605 | return Convert.ToInt32(field.Data); | 793 | return Convert.ToInt32(field.Data); |
606 | } | 794 | } |
607 | } | 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 | } | ||
608 | } | 810 | } |
609 | } | 811 | } |
diff --git a/src/test/WixToolsetTest.Converters.Tupleizer/ConvertTuplesFixture.cs b/src/test/WixToolsetTest.Converters.Tupleizer/ConvertTuplesFixture.cs index ae33d6b1..9b1fa4cf 100644 --- a/src/test/WixToolsetTest.Converters.Tupleizer/ConvertTuplesFixture.cs +++ b/src/test/WixToolsetTest.Converters.Tupleizer/ConvertTuplesFixture.cs | |||
@@ -3,6 +3,7 @@ | |||
3 | namespace WixToolsetTest.Converters.Tupleizer | 3 | namespace WixToolsetTest.Converters.Tupleizer |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections.Generic; | ||
6 | using System.IO; | 7 | using System.IO; |
7 | using System.Linq; | 8 | using System.Linq; |
8 | using WixBuildTools.TestSupport; | 9 | using WixBuildTools.TestSupport; |
@@ -42,350 +43,512 @@ namespace WixToolsetTest.Converters.Tupleizer | |||
42 | 43 | ||
43 | intermediate = Intermediate.Load(wixiplFile); | 44 | intermediate = Intermediate.Load(wixiplFile); |
44 | 45 | ||
46 | var wixMediaByDiskId = IndexWixMediaTableByDiskId(output); | ||
47 | |||
45 | // Dump to text for easy diffing, with some massaging to keep v3 and v4 diffable. | 48 | // Dump to text for easy diffing, with some massaging to keep v3 and v4 diffable. |
46 | // | 49 | // |
47 | var tables = output.Tables.Cast<Wix3.Table>(); | 50 | var tables = output.Tables.Cast<Wix3.Table>(); |
48 | var wix3Dump = tables | 51 | var wix3Dump = tables |
49 | .SelectMany(table => table.Rows.Cast<Wix3.Row>() | 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) | ||
51 | .ToArray(); | 56 | .ToArray(); |
52 | 57 | ||
53 | var tuples = intermediate.Sections.SelectMany(s => s.Tuples); | 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(); | ||
55 | 63 | ||
64 | #if false | ||
56 | Assert.Equal(wix3Dump, wix4Dump); | 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); | ||
57 | 69 | ||
58 | // Useful when you want to diff the outputs with another diff tool... | 70 | File.WriteAllText(Path.Combine(Path.GetTempPath(), "~3.txt"), wix3TextDump); |
59 | // | 71 | File.WriteAllText(Path.Combine(Path.GetTempPath(), "~4.txt"), wix4TextDump); |
60 | //var wix3TextDump = String.Join(Environment.NewLine, wix3Dump.OrderBy(val => val)); | 72 | |
61 | //var wix4TextDump = String.Join(Environment.NewLine, wix4Dump.OrderBy(val => val)); | 73 | Assert.Equal(wix3TextDump, wix4TextDump); |
62 | //Assert.Equal(wix3TextDump, wix4TextDump); | 74 | #endif |
63 | } | 75 | } |
64 | } | 76 | } |
65 | 77 | ||
66 | private static string RowToString(Wix3.Row row) | 78 | private static Dictionary<int, Wix3.WixMediaRow> IndexWixMediaTableByDiskId(Wix3.Output output) |
67 | { | 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"]; | ||
69 | 82 | ||
70 | // Massage output to match WiX v3 rows and v4 tuples. | 83 | if (wixMediaTable != null) |
71 | // | ||
72 | switch (row.Table.Name) | ||
73 | { | 84 | { |
74 | case "File": | 85 | foreach (Wix3.WixMediaRow row in wixMediaTable.Rows) |
75 | var fieldValues = row.Fields.Take(7).Select(field => field.Data?.ToString()).ToArray(); | 86 | { |
76 | if (fieldValues[3] == null) | 87 | wixMediaByDiskId.Add((int)row[0], row); |
77 | { | 88 | } |
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; | ||
87 | } | 89 | } |
88 | 90 | ||
89 | return $"{row.Table.Name},{fields}"; | 91 | return wixMediaByDiskId; |
90 | } | 92 | } |
91 | 93 | ||
92 | private static string TupleToString(WixToolset.Data.IntermediateTuple tuple) | 94 | private static IEnumerable<string> RowToStrings(Wix3.Row row, Dictionary<int, Wix3.WixMediaRow> wixMediaByDiskId) |
93 | { | 95 | { |
94 | var fields = String.Join(",", tuple.Fields.Select(field => field?.AsString())); | 96 | string fields = null; |
95 | 97 | ||
96 | switch (tuple.Definition.Name) | 98 | // Massage output to match WiX v3 rows and v4 tuples. |
99 | // | ||
100 | switch (row.Table.Name) | ||
97 | { | 101 | { |
98 | // Massage output to match WiX v3 rows and v4 tuples. | 102 | case "Directory": |
99 | // | 103 | var dirs = SplitDefaultDir((string)row[2]); |
100 | case "Component": | 104 | fields = String.Join(",", row[0], row[1], dirs[0], dirs[1], dirs[2], dirs[3]); |
101 | { | 105 | break; |
102 | var componentTuple = (ComponentTuple)tuple; | 106 | case "File": |
103 | var attributes = ComponentLocation.Either == componentTuple.Location ? WindowsInstallerConstants.MsidbComponentAttributesOptional : 0; | 107 | { |
104 | attributes |= ComponentLocation.SourceOnly == componentTuple.Location ? WindowsInstallerConstants.MsidbComponentAttributesSourceOnly : 0; | 108 | var fieldValues = row.Fields.Take(7).Select(SafeConvertField).ToArray(); |
105 | attributes |= ComponentKeyPathType.Registry == componentTuple.KeyPathType ? WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath : 0; | 109 | if (fieldValues[3] == null) |
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": | ||
126 | { | 110 | { |
127 | var customActionTuple = (CustomActionTuple)tuple; | 111 | // "Somebody" sometimes writes out a null field even when the column definition says |
128 | var type = customActionTuple.Win64 ? WindowsInstallerConstants.MsidbCustomActionType64BitScript : 0; | 112 | // it's non-nullable. Not naming names or anything. (SWID tags.) |
129 | type |= customActionTuple.TSAware ? WindowsInstallerConstants.MsidbCustomActionTypeTSAware : 0; | 113 | fieldValues[3] = "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; | ||
156 | } | 114 | } |
157 | case "Feature": | 115 | fields = String.Join(",", fieldValues); |
158 | { | 116 | break; |
159 | var featureTuple = (FeatureTuple)tuple; | 117 | } |
160 | var attributes = featureTuple.DisallowAbsent ? WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent : 0; | 118 | case "Media": |
161 | attributes |= featureTuple.DisallowAdvertise ? WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise : 0; | 119 | var compression = wixMediaByDiskId.TryGetValue((int)row[0], out var wixMedia) ? (CompressionLevel?)Enum.Parse(typeof(CompressionLevel), SafeConvertField(wixMedia.Fields[1]), true) : null; |
162 | attributes |= FeatureInstallDefault.FollowParent == featureTuple.InstallDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFollowParent : 0; | 120 | |
163 | attributes |= FeatureInstallDefault.Source == featureTuple.InstallDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFavorSource : 0; | 121 | fields = String.Join(",", row.Fields.Select(SafeConvertField)); |
164 | attributes |= FeatureTypicalDefault.Advertise == featureTuple.TypicalDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise : 0; | 122 | fields = String.Join(",", fields, (int?)compression, SafeConvertField(wixMedia?.Fields[2])); |
165 | 123 | break; | |
166 | fields = String.Join(",", | 124 | case "RegLocator": |
167 | featureTuple.Feature_Parent, | 125 | var type = (int)row[4]; |
168 | featureTuple.Title, | 126 | fields = String.Join(",", row[0], row[1], row[2], row[3], type & 0xF, (type & 0x10) == 0x10); |
169 | featureTuple.Description, | 127 | break; |
170 | featureTuple.Display.ToString(), | 128 | case "RemoveFile": |
171 | featureTuple.Level.ToString(), | 129 | var attributes = (int)row[4]; |
172 | featureTuple.Directory_, | 130 | var onInstall = (attributes & 1) == 1 ? (bool?)true : null; |
173 | attributes.ToString()); | 131 | var onUninstall = (attributes & 2) == 2 ? (bool?)true : null; |
174 | break; | 132 | fields = String.Join(",", row.Fields.Take(4).Select(SafeConvertField)); |
175 | } | 133 | fields = String.Join(",", fields, onInstall, onUninstall); |
176 | case "File": | 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) | ||
177 | { | 148 | { |
178 | var fileTuple = (FileTuple)tuple; | 149 | // "Somebody" sometimes writes out a null field even when the column definition says |
179 | fields = String.Join(",", | 150 | // it's non-nullable. Not naming names or anything. (SWID tags.) |
180 | fileTuple.Component_, | 151 | fieldValues[8] = "0"; |
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; | ||
194 | } | 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 | } | ||
195 | 162 | ||
196 | case "Registry": | 163 | if (fields != null) |
197 | { | 164 | { |
198 | var registryTuple = (RegistryTuple)tuple; | 165 | yield return $"{row.Table.Name}:{fields}"; |
199 | var value = registryTuple.Value; | 166 | } |
200 | 167 | } | |
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 | } | ||
238 | 168 | ||
239 | fields = String.Join(",", | 169 | private static IEnumerable<string> TupleToStrings(IntermediateTuple tuple) |
240 | ((int)registryTuple.Root).ToString(), | 170 | { |
241 | registryTuple.Key, | 171 | string fields; |
242 | registryTuple.Name, | 172 | switch (tuple.Definition.Name) |
243 | value, | 173 | { |
244 | registryTuple.Component_ | 174 | // Massage output to match WiX v3 rows and v4 tuples. |
245 | ); | 175 | // |
246 | break; | 176 | case "Component": |
247 | } | 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; | ||
248 | 236 | ||
249 | case "RemoveRegistry": | 237 | if (!String.IsNullOrEmpty(directoryTuple.ComponentGuidGenerationSeed)) |
250 | { | 238 | { |
251 | var removeRegistryTuple = (RemoveRegistryTuple)tuple; | 239 | yield return $"WixDirectory:{directoryTuple.Id.Id},{directoryTuple.ComponentGuidGenerationSeed}"; |
252 | fields = String.Join(",", | ||
253 | ((int)removeRegistryTuple.Root).ToString(), | ||
254 | removeRegistryTuple.Key, | ||
255 | removeRegistryTuple.Name, | ||
256 | removeRegistryTuple.Component_ | ||
257 | ); | ||
258 | break; | ||
259 | } | 240 | } |
260 | 241 | ||
261 | case "ServiceControl": | 242 | fields = String.Join(",", directoryTuple.ParentDirectoryRef, directoryTuple.Name, directoryTuple.ShortName, directoryTuple.SourceName, directoryTuple.SourceShortName); |
262 | { | 243 | break; |
263 | var serviceControlTuple = (ServiceControlTuple)tuple; | 244 | } |
264 | 245 | case "Feature": | |
265 | var events = serviceControlTuple.InstallRemove ? WindowsInstallerConstants.MsidbServiceControlEventDelete : 0; | 246 | { |
266 | events |= serviceControlTuple.UninstallRemove ? WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete : 0; | 247 | var featureTuple = (FeatureTuple)tuple; |
267 | events |= serviceControlTuple.InstallStart ? WindowsInstallerConstants.MsidbServiceControlEventStart : 0; | 248 | var attributes = featureTuple.DisallowAbsent ? WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent : 0; |
268 | events |= serviceControlTuple.UninstallStart ? WindowsInstallerConstants.MsidbServiceControlEventUninstallStart : 0; | 249 | attributes |= featureTuple.DisallowAdvertise ? WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise : 0; |
269 | events |= serviceControlTuple.InstallStop ? WindowsInstallerConstants.MsidbServiceControlEventStop : 0; | 250 | attributes |= FeatureInstallDefault.FollowParent == featureTuple.InstallDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFollowParent : 0; |
270 | events |= serviceControlTuple.UninstallStop ? WindowsInstallerConstants.MsidbServiceControlEventUninstallStop : 0; | 251 | attributes |= FeatureInstallDefault.Source == featureTuple.InstallDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFavorSource : 0; |
271 | 252 | attributes |= FeatureTypicalDefault.Advertise == featureTuple.TypicalDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise : 0; | |
272 | fields = String.Join(",", | 253 | |
273 | serviceControlTuple.Name, | 254 | fields = String.Join(",", |
274 | events.ToString(), | 255 | featureTuple.ParentFeatureRef, |
275 | serviceControlTuple.Arguments, | 256 | featureTuple.Title, |
276 | serviceControlTuple.Wait == true ? "1" : "0", | 257 | featureTuple.Description, |
277 | serviceControlTuple.Component_ | 258 | featureTuple.Display.ToString(), |
278 | ); | 259 | featureTuple.Level.ToString(), |
279 | break; | 260 | featureTuple.DirectoryRef, |
280 | } | 261 | attributes.ToString()); |
262 | break; | ||
263 | } | ||
264 | case "File": | ||
265 | { | ||
266 | var fileTuple = (FileTuple)tuple; | ||
281 | 267 | ||
282 | case "ServiceInstall": | 268 | if (fileTuple.BindPath != null) |
283 | { | 269 | { |
284 | var serviceInstallTuple = (ServiceInstallTuple)tuple; | 270 | yield return $"BindImage:{fileTuple.Id.Id},{fileTuple.BindPath}"; |
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; | ||
307 | } | 271 | } |
308 | 272 | ||
309 | case "Upgrade": | 273 | if (fileTuple.FontTitle != null) |
310 | { | 274 | { |
311 | var upgradeTuple = (UpgradeTuple)tuple; | 275 | yield return $"Font:{fileTuple.Id.Id},{fileTuple.FontTitle}"; |
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; | ||
329 | } | 276 | } |
330 | 277 | ||
331 | case "WixAction": | 278 | if (fileTuple.SelfRegCost.HasValue) |
332 | { | 279 | { |
333 | var wixActionTuple = (WixActionTuple)tuple; | 280 | yield return $"SelfReg:{fileTuple.Id.Id},{fileTuple.SelfRegCost}"; |
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; | ||
345 | } | 281 | } |
346 | 282 | ||
347 | case "WixComplexReference": | 283 | fields = String.Join(",", |
348 | { | 284 | fileTuple.ComponentRef, |
349 | var wixComplexReferenceTuple = (WixComplexReferenceTuple)tuple; | 285 | fileTuple.Name, |
350 | fields = String.Join(",", | 286 | fileTuple.FileSize.ToString(), |
351 | wixComplexReferenceTuple.Parent, | 287 | fileTuple.Version, |
352 | ((int)wixComplexReferenceTuple.ParentType).ToString(), | 288 | fileTuple.Language, |
353 | wixComplexReferenceTuple.ParentLanguage, | 289 | ((fileTuple.ReadOnly ? WindowsInstallerConstants.MsidbFileAttributesReadOnly : 0) |
354 | wixComplexReferenceTuple.Child, | 290 | | (fileTuple.Hidden ? WindowsInstallerConstants.MsidbFileAttributesHidden : 0) |
355 | ((int)wixComplexReferenceTuple.ChildType).ToString(), | 291 | | (fileTuple.System ? WindowsInstallerConstants.MsidbFileAttributesSystem : 0) |
356 | wixComplexReferenceTuple.IsPrimary ? "1" : "0" | 292 | | (fileTuple.Vital ? WindowsInstallerConstants.MsidbFileAttributesVital : 0) |
357 | ); | 293 | | (fileTuple.Checksum ? WindowsInstallerConstants.MsidbFileAttributesChecksum : 0) |
358 | break; | 294 | | ((fileTuple.Compressed.HasValue && fileTuple.Compressed.Value) ? WindowsInstallerConstants.MsidbFileAttributesCompressed : 0) |
359 | } | 295 | | ((fileTuple.Compressed.HasValue && !fileTuple.Compressed.Value) ? WindowsInstallerConstants.MsidbFileAttributesNoncompressed : 0)) |
296 | .ToString()); | ||
297 | break; | ||
298 | } | ||
360 | 299 | ||
361 | case "WixFile": | 300 | case "Media": |
362 | { | 301 | fields = String.Join(",", tuple.Fields.Skip(1).Select(SafeConvertField)); |
363 | var wixFileTuple = (WixFileTuple)tuple; | 302 | break; |
364 | fields = String.Concat( | 303 | |
365 | wixFileTuple.AssemblyType == FileAssemblyType.DotNetAssembly ? "0" : wixFileTuple.AssemblyType == FileAssemblyType.Win32Assembly ? "1" : String.Empty, ",", | 304 | case "Registry": |
366 | String.Join(",", tuple.Fields.Skip(2).Take(6).Select(field => (string)field).ToArray())); | 305 | { |
367 | break; | 306 | var registryTuple = (RegistryTuple)tuple; |
368 | } | 307 | var value = registryTuple.Value; |
369 | 308 | ||
370 | case "WixProperty": | 309 | switch (registryTuple.ValueType) |
371 | { | 310 | { |
372 | var wixPropertyTuple = (WixPropertyTuple)tuple; | 311 | case RegistryValueType.Binary: |
373 | var attributes = 0; | 312 | value = String.Concat("#x", value); |
374 | attributes |= wixPropertyTuple.Admin ? 0x1 : 0; | 313 | break; |
375 | attributes |= wixPropertyTuple.Hidden ? 0x2 : 0; | 314 | case RegistryValueType.Expandable: |
376 | attributes |= wixPropertyTuple.Secure ? 0x4 : 0; | 315 | value = String.Concat("#%", value); |
377 | 316 | break; | |
378 | fields = String.Join(",", | 317 | case RegistryValueType.Integer: |
379 | wixPropertyTuple.Property_, | 318 | value = String.Concat("#", value); |
380 | attributes.ToString() | 319 | break; |
381 | ); | 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 | } | ||
382 | break; | 344 | break; |
383 | } | 345 | } |
384 | 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}"); | ||
385 | } | 521 | } |
522 | } | ||
386 | 523 | ||
387 | var id = tuple.Id == null ? String.Empty : String.Concat(",", tuple.Id.Id); | 524 | private static string SafeConvertField(Wix3.Field field) |
388 | return $"{tuple.Definition.Name}{id},{fields}"; | 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 | }; | ||
389 | } | 552 | } |
390 | } | 553 | } |
391 | } | 554 | } |