Support instance transforms
Rob Mensching committed
May 23, 2020 at 01:57 UTC
c4497aa78b2d85b2613af64311bf282756aff43a
3 files changed
+297
-243
src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+2
-241
@@ -373,9 +373,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
373
}
374
else // we can create instance transforms since Component Guids are set.
375
{
376
-#if TODO_FIX_INSTANCE_TRANSFORM
377
- this.CreateInstanceTransforms(this.Output);
378
-#endif
376
+ var command = new CreateInstanceTransformsCommand(section, output, tableDefinitions, this.BackendHelper);
377
+ command.Execute();
378
}
379
380
#if TODO_FINISH_UPDATE
@@ -640,244 +639,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
639
}
640
#endif
641
643
-
644
-#if TODO_FIX_INSTANCE_TRANSFORM
645
- /// <summary>
646
- /// Creates instance transform substorages in the output.
647
- /// </summary>
648
- /// <param name="output">Output containing instance transform definitions.</param>
649
- private void CreateInstanceTransforms(Output output)
650
- {
651
- // Create and add substorages for instance transforms.
652
- Table wixInstanceTransformsTable = output.Tables["WixInstanceTransforms"];
653
- if (null != wixInstanceTransformsTable && 0 <= wixInstanceTransformsTable.Rows.Count)
654
- {
655
- string targetProductCode = null;
656
- string targetUpgradeCode = null;
657
- string targetProductVersion = null;
658
-
659
- Table targetSummaryInformationTable = output.Tables["_SummaryInformation"];
660
- Table targetPropertyTable = output.Tables["Property"];
661
-
662
- // Get the data from target database
663
- foreach (Row propertyRow in targetPropertyTable.Rows)
664
- {
665
- if ("ProductCode" == (string)propertyRow[0])
666
- {
667
- targetProductCode = (string)propertyRow[1];
668
- }
669
- else if ("ProductVersion" == (string)propertyRow[0])
670
- {
671
- targetProductVersion = (string)propertyRow[1];
672
- }
673
- else if ("UpgradeCode" == (string)propertyRow[0])
674
- {
675
- targetUpgradeCode = (string)propertyRow[1];
676
- }
677
- }
678
-
679
- // Index the Instance Component Rows.
680
- Dictionary<string, ComponentRow> instanceComponentGuids = new Dictionary<string, ComponentRow>();
681
- Table targetInstanceComponentTable = output.Tables["WixInstanceComponent"];
682
- if (null != targetInstanceComponentTable && 0 < targetInstanceComponentTable.Rows.Count)
683
- {
684
- foreach (Row row in targetInstanceComponentTable.Rows)
685
- {
686
- // Build up all the instances, we'll get the Components rows from the real Component table.
687
- instanceComponentGuids.Add((string)row[0], null);
688
- }
689
-
690
- Table targetComponentTable = output.Tables["Component"];
691
- foreach (ComponentRow componentRow in targetComponentTable.Rows)
692
- {
693
- string component = (string)componentRow[0];
694
- if (instanceComponentGuids.ContainsKey(component))
695
- {
696
- instanceComponentGuids[component] = componentRow;
697
- }
698
- }
699
- }
700
-
701
- // Generate the instance transforms
702
- foreach (Row instanceRow in wixInstanceTransformsTable.Rows)
703
- {
704
- string instanceId = (string)instanceRow[0];
705
-
706
- Output instanceTransform = new Output(instanceRow.SourceLineNumbers);
707
- instanceTransform.Type = OutputType.Transform;
708
- instanceTransform.Codepage = output.Codepage;
709
-
710
- Table instanceSummaryInformationTable = instanceTransform.EnsureTable(this.TableDefinitions["_SummaryInformation"]);
711
- string targetPlatformAndLanguage = null;
712
-
713
- foreach (Row summaryInformationRow in targetSummaryInformationTable.Rows)
714
- {
715
- if (7 == (int)summaryInformationRow[0]) // PID_TEMPLATE
716
- {
717
- targetPlatformAndLanguage = (string)summaryInformationRow[1];
718
- }
719
-
720
- // Copy the row's data to the transform.
721
- Row copyOfSummaryRow = instanceSummaryInformationTable.CreateRow(null);
722
- copyOfSummaryRow[0] = summaryInformationRow[0];
723
- copyOfSummaryRow[1] = summaryInformationRow[1];
724
- }
725
-
726
- // Modify the appropriate properties.
727
- Table propertyTable = instanceTransform.EnsureTable(this.TableDefinitions["Property"]);
728
-
729
- // Change the ProductCode property
730
- string productCode = (string)instanceRow[2];
731
- if ("*" == productCode)
732
- {
733
- productCode = Common.GenerateGuid();
734
- }
735
-
736
- Row productCodeRow = propertyTable.CreateRow(instanceRow.SourceLineNumbers);
737
- productCodeRow.Operation = RowOperation.Modify;
738
- productCodeRow.Fields[1].Modified = true;
739
- productCodeRow[0] = "ProductCode";
740
- productCodeRow[1] = productCode;
741
-
742
- // Change the instance property
743
- Row instanceIdRow = propertyTable.CreateRow(instanceRow.SourceLineNumbers);
744
- instanceIdRow.Operation = RowOperation.Modify;
745
- instanceIdRow.Fields[1].Modified = true;
746
- instanceIdRow[0] = (string)instanceRow[1];
747
- instanceIdRow[1] = instanceId;
748
-
749
- if (null != instanceRow[3])
750
- {
751
- // Change the ProductName property
752
- Row productNameRow = propertyTable.CreateRow(instanceRow.SourceLineNumbers);
753
- productNameRow.Operation = RowOperation.Modify;
754
- productNameRow.Fields[1].Modified = true;
755
- productNameRow[0] = "ProductName";
756
- productNameRow[1] = (string)instanceRow[3];
757
- }
758
-
759
- if (null != instanceRow[4])
760
- {
761
- // Change the UpgradeCode property
762
- Row upgradeCodeRow = propertyTable.CreateRow(instanceRow.SourceLineNumbers);
763
- upgradeCodeRow.Operation = RowOperation.Modify;
764
- upgradeCodeRow.Fields[1].Modified = true;
765
- upgradeCodeRow[0] = "UpgradeCode";
766
- upgradeCodeRow[1] = instanceRow[4];
767
-
768
- // Change the Upgrade table
769
- Table targetUpgradeTable = output.Tables["Upgrade"];
770
- if (null != targetUpgradeTable && 0 <= targetUpgradeTable.Rows.Count)
771
- {
772
- string upgradeId = (string)instanceRow[4];
773
- Table upgradeTable = instanceTransform.EnsureTable(this.TableDefinitions["Upgrade"]);
774
- foreach (Row row in targetUpgradeTable.Rows)
775
- {
776
- // In case they are upgrading other codes to this new product, leave the ones that don't match the
777
- // Product.UpgradeCode intact.
778
- if (targetUpgradeCode == (string)row[0])
779
- {
780
- Row upgradeRow = upgradeTable.CreateRow(null);
781
- upgradeRow.Operation = RowOperation.Add;
782
- upgradeRow.Fields[0].Modified = true;
783
- // I was hoping to be able to RowOperation.Modify, but that didn't appear to function.
784
- // upgradeRow.Fields[0].PreviousData = (string)row[0];
785
-
786
- // Inserting a new Upgrade record with the updated UpgradeCode
787
- upgradeRow[0] = upgradeId;
788
- upgradeRow[1] = row[1];
789
- upgradeRow[2] = row[2];
790
- upgradeRow[3] = row[3];
791
- upgradeRow[4] = row[4];
792
- upgradeRow[5] = row[5];
793
- upgradeRow[6] = row[6];
794
-
795
- // Delete the old row
796
- Row upgradeRemoveRow = upgradeTable.CreateRow(null);
797
- upgradeRemoveRow.Operation = RowOperation.Delete;
798
- upgradeRemoveRow[0] = row[0];
799
- upgradeRemoveRow[1] = row[1];
800
- upgradeRemoveRow[2] = row[2];
801
- upgradeRemoveRow[3] = row[3];
802
- upgradeRemoveRow[4] = row[4];
803
- upgradeRemoveRow[5] = row[5];
804
- upgradeRemoveRow[6] = row[6];
805
- }
806
- }
807
- }
808
- }
809
-
810
- // If there are instance Components generate new GUIDs for them.
811
- if (0 < instanceComponentGuids.Count)
812
- {
813
- Table componentTable = instanceTransform.EnsureTable(this.TableDefinitions["Component"]);
814
- foreach (ComponentRow targetComponentRow in instanceComponentGuids.Values)
815
- {
816
- string guid = targetComponentRow.Guid;
817
- if (!String.IsNullOrEmpty(guid))
818
- {
819
- Row instanceComponentRow = componentTable.CreateRow(targetComponentRow.SourceLineNumbers);
820
- instanceComponentRow.Operation = RowOperation.Modify;
821
- instanceComponentRow.Fields[1].Modified = true;
822
- instanceComponentRow[0] = targetComponentRow[0];
823
- instanceComponentRow[1] = Uuid.NewUuid(BindDatabaseCommand.WixComponentGuidNamespace, String.Concat(guid, instanceId)).ToString("B").ToUpper(CultureInfo.InvariantCulture);
824
- instanceComponentRow[2] = targetComponentRow[2];
825
- instanceComponentRow[3] = targetComponentRow[3];
826
- instanceComponentRow[4] = targetComponentRow[4];
827
- instanceComponentRow[5] = targetComponentRow[5];
828
- }
829
- }
830
- }
831
-
832
- // Update the summary information
833
- Hashtable summaryRows = new Hashtable(instanceSummaryInformationTable.Rows.Count);
834
- foreach (Row row in instanceSummaryInformationTable.Rows)
835
- {
836
- summaryRows[row[0]] = row;
837
-
838
- if ((int)SummaryInformation.Transform.UpdatedPlatformAndLanguage == (int)row[0])
839
- {
840
- row[1] = targetPlatformAndLanguage;
841
- }
842
- else if ((int)SummaryInformation.Transform.ProductCodes == (int)row[0])
843
- {
844
- row[1] = String.Concat(targetProductCode, targetProductVersion, ';', productCode, targetProductVersion, ';', targetUpgradeCode);
845
- }
846
- else if ((int)SummaryInformation.Transform.ValidationFlags == (int)row[0])
847
- {
848
- row[1] = 0;
849
- }
850
- else if ((int)SummaryInformation.Transform.Security == (int)row[0])
851
- {
852
- row[1] = "4";
853
- }
854
- }
855
-
856
- if (!summaryRows.Contains((int)SummaryInformation.Transform.UpdatedPlatformAndLanguage))
857
- {
858
- Row summaryRow = instanceSummaryInformationTable.CreateRow(null);
859
- summaryRow[0] = (int)SummaryInformation.Transform.UpdatedPlatformAndLanguage;
860
- summaryRow[1] = targetPlatformAndLanguage;
861
- }
862
- else if (!summaryRows.Contains((int)SummaryInformation.Transform.ValidationFlags))
863
- {
864
- Row summaryRow = instanceSummaryInformationTable.CreateRow(null);
865
- summaryRow[0] = (int)SummaryInformation.Transform.ValidationFlags;
866
- summaryRow[1] = "0";
867
- }
868
- else if (!summaryRows.Contains((int)SummaryInformation.Transform.Security))
869
- {
870
- Row summaryRow = instanceSummaryInformationTable.CreateRow(null);
871
- summaryRow[0] = (int)SummaryInformation.Transform.Security;
872
- summaryRow[1] = "4";
873
- }
874
-
875
- output.SubStorages.Add(new SubStorage(instanceId, instanceTransform));
876
- }
877
- }
878
- }
879
-#endif
880
-
642
/// <summary>
643
/// Validate that there are no duplicate GUIDs in the output.
644
/// </summary>
src/WixToolset.Core.WindowsInstaller/Bind/CreateInstanceTransformsCommand.cs
new
+260
@@ -0,0 +1,260 @@
1
+// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
+
3
+namespace WixToolset.Core.WindowsInstaller.Bind
4
+{
5
+ using System;
6
+ using System.Collections.Generic;
7
+ using System.Linq;
8
+ using WixToolset.Core.WindowsInstaller.Msi;
9
+ using WixToolset.Data;
10
+ using WixToolset.Data.Tuples;
11
+ using WixToolset.Data.WindowsInstaller;
12
+ using WixToolset.Data.WindowsInstaller.Rows;
13
+ using WixToolset.Extensibility.Services;
14
+
15
+ internal class CreateInstanceTransformsCommand
16
+ {
17
+ public CreateInstanceTransformsCommand(IntermediateSection section, WindowsInstallerData output, TableDefinitionCollection tableDefinitions, IBackendHelper backendHelper)
18
+ {
19
+ this.Section = section;
20
+ this.Output = output;
21
+ this.TableDefinitions = tableDefinitions;
22
+ this.BackendHelper = backendHelper;
23
+ }
24
+
25
+ private IntermediateSection Section { get; }
26
+
27
+ private WindowsInstallerData Output { get; }
28
+
29
+ public TableDefinitionCollection TableDefinitions { get; }
30
+
31
+ private IBackendHelper BackendHelper { get; }
32
+
33
+ public void Execute()
34
+ {
35
+ // Create and add substorages for instance transforms.
36
+ var wixInstanceTransformsTuples = this.Section.Tuples.OfType<WixInstanceTransformsTuple>();
37
+
38
+ if (wixInstanceTransformsTuples.Any())
39
+ {
40
+ string targetProductCode = null;
41
+ string targetUpgradeCode = null;
42
+ string targetProductVersion = null;
43
+
44
+ var targetSummaryInformationTable = this.Output.Tables["_SummaryInformation"];
45
+ var targetPropertyTable = this.Output.Tables["Property"];
46
+
47
+ // Get the data from target database
48
+ foreach (var propertyRow in targetPropertyTable.Rows)
49
+ {
50
+ if ("ProductCode" == (string)propertyRow[0])
51
+ {
52
+ targetProductCode = (string)propertyRow[1];
53
+ }
54
+ else if ("ProductVersion" == (string)propertyRow[0])
55
+ {
56
+ targetProductVersion = (string)propertyRow[1];
57
+ }
58
+ else if ("UpgradeCode" == (string)propertyRow[0])
59
+ {
60
+ targetUpgradeCode = (string)propertyRow[1];
61
+ }
62
+ }
63
+
64
+ // Index the Instance Component Rows, we'll get the Components rows from the real Component table.
65
+ var targetInstanceComponentTable = this.Section.Tuples.OfType<WixInstanceComponentTuple>();
66
+ var instanceComponentGuids = targetInstanceComponentTable.ToDictionary(t => t.Id.Id, t => (ComponentRow)null);
67
+
68
+ if (instanceComponentGuids.Any())
69
+ {
70
+ var targetComponentTable = this.Output.Tables["Component"];
71
+ foreach (ComponentRow componentRow in targetComponentTable.Rows)
72
+ {
73
+ var component = (string)componentRow[0];
74
+ if (instanceComponentGuids.ContainsKey(component))
75
+ {
76
+ instanceComponentGuids[component] = componentRow;
77
+ }
78
+ }
79
+ }
80
+
81
+ // Generate the instance transforms
82
+ foreach (var instanceTuple in wixInstanceTransformsTuples)
83
+ {
84
+ var instanceId = instanceTuple.Id.Id;
85
+
86
+ var instanceTransform = new WindowsInstallerData(instanceTuple.SourceLineNumbers);
87
+ instanceTransform.Type = OutputType.Transform;
88
+ instanceTransform.Codepage = this.Output.Codepage;
89
+
90
+ var instanceSummaryInformationTable = instanceTransform.EnsureTable(this.TableDefinitions["_SummaryInformation"]);
91
+ string targetPlatformAndLanguage = null;
92
+
93
+ foreach (var summaryInformationRow in targetSummaryInformationTable.Rows)
94
+ {
95
+ if (7 == (int)summaryInformationRow[0]) // PID_TEMPLATE
96
+ {
97
+ targetPlatformAndLanguage = (string)summaryInformationRow[1];
98
+ }
99
+
100
+ // Copy the row's data to the transform.
101
+ var copyOfSummaryRow = instanceSummaryInformationTable.CreateRow(summaryInformationRow.SourceLineNumbers);
102
+ copyOfSummaryRow[0] = summaryInformationRow[0];
103
+ copyOfSummaryRow[1] = summaryInformationRow[1];
104
+ }
105
+
106
+ // Modify the appropriate properties.
107
+ var propertyTable = instanceTransform.EnsureTable(this.TableDefinitions["Property"]);
108
+
109
+ // Change the ProductCode property
110
+ var productCode = instanceTuple.ProductCode;
111
+ if ("*" == productCode)
112
+ {
113
+ productCode = Common.GenerateGuid();
114
+ }
115
+
116
+ var productCodeRow = propertyTable.CreateRow(instanceTuple.SourceLineNumbers);
117
+ productCodeRow.Operation = RowOperation.Modify;
118
+ productCodeRow.Fields[1].Modified = true;
119
+ productCodeRow[0] = "ProductCode";
120
+ productCodeRow[1] = productCode;
121
+
122
+ // Change the instance property
123
+ var instanceIdRow = propertyTable.CreateRow(instanceTuple.SourceLineNumbers);
124
+ instanceIdRow.Operation = RowOperation.Modify;
125
+ instanceIdRow.Fields[1].Modified = true;
126
+ instanceIdRow[0] = instanceTuple.PropertyId;
127
+ instanceIdRow[1] = instanceId;
128
+
129
+ if (!String.IsNullOrEmpty(instanceTuple.ProductName))
130
+ {
131
+ // Change the ProductName property
132
+ var productNameRow = propertyTable.CreateRow(instanceTuple.SourceLineNumbers);
133
+ productNameRow.Operation = RowOperation.Modify;
134
+ productNameRow.Fields[1].Modified = true;
135
+ productNameRow[0] = "ProductName";
136
+ productNameRow[1] = instanceTuple.ProductName;
137
+ }
138
+
139
+ if (!String.IsNullOrEmpty(instanceTuple.UpgradeCode))
140
+ {
141
+ // Change the UpgradeCode property
142
+ var upgradeCodeRow = propertyTable.CreateRow(instanceTuple.SourceLineNumbers);
143
+ upgradeCodeRow.Operation = RowOperation.Modify;
144
+ upgradeCodeRow.Fields[1].Modified = true;
145
+ upgradeCodeRow[0] = "UpgradeCode";
146
+ upgradeCodeRow[1] = instanceTuple.UpgradeCode;
147
+
148
+ // Change the Upgrade table
149
+ var targetUpgradeTable = this.Output.Tables["Upgrade"];
150
+ if (null != targetUpgradeTable && 0 <= targetUpgradeTable.Rows.Count)
151
+ {
152
+ var upgradeId = instanceTuple.UpgradeCode;
153
+ var upgradeTable = instanceTransform.EnsureTable(this.TableDefinitions["Upgrade"]);
154
+ foreach (var row in targetUpgradeTable.Rows)
155
+ {
156
+ // In case they are upgrading other codes to this new product, leave the ones that don't match the
157
+ // Product.UpgradeCode intact.
158
+ if (targetUpgradeCode == (string)row[0])
159
+ {
160
+ var upgradeRow = upgradeTable.CreateRow(row.SourceLineNumbers);
161
+ upgradeRow.Operation = RowOperation.Add;
162
+ upgradeRow.Fields[0].Modified = true;
163
+ // I was hoping to be able to RowOperation.Modify, but that didn't appear to function.
164
+ // upgradeRow.Fields[0].PreviousData = (string)row[0];
165
+
166
+ // Inserting a new Upgrade record with the updated UpgradeCode
167
+ upgradeRow[0] = upgradeId;
168
+ upgradeRow[1] = row[1];
169
+ upgradeRow[2] = row[2];
170
+ upgradeRow[3] = row[3];
171
+ upgradeRow[4] = row[4];
172
+ upgradeRow[5] = row[5];
173
+ upgradeRow[6] = row[6];
174
+
175
+ // Delete the old row
176
+ var upgradeRemoveRow = upgradeTable.CreateRow(row.SourceLineNumbers);
177
+ upgradeRemoveRow.Operation = RowOperation.Delete;
178
+ upgradeRemoveRow[0] = row[0];
179
+ upgradeRemoveRow[1] = row[1];
180
+ upgradeRemoveRow[2] = row[2];
181
+ upgradeRemoveRow[3] = row[3];
182
+ upgradeRemoveRow[4] = row[4];
183
+ upgradeRemoveRow[5] = row[5];
184
+ upgradeRemoveRow[6] = row[6];
185
+ }
186
+ }
187
+ }
188
+ }
189
+
190
+ // If there are instance Components generate new GUIDs for them.
191
+ if (0 < instanceComponentGuids.Count)
192
+ {
193
+ var componentTable = instanceTransform.EnsureTable(this.TableDefinitions["Component"]);
194
+ foreach (var targetComponentRow in instanceComponentGuids.Values)
195
+ {
196
+ var guid = targetComponentRow.Guid;
197
+ if (!String.IsNullOrEmpty(guid))
198
+ {
199
+ var instanceComponentRow = componentTable.CreateRow(targetComponentRow.SourceLineNumbers);
200
+ instanceComponentRow.Operation = RowOperation.Modify;
201
+ instanceComponentRow.Fields[1].Modified = true;
202
+ instanceComponentRow[0] = targetComponentRow[0];
203
+ instanceComponentRow[1] = this.BackendHelper.CreateGuid(BindDatabaseCommand.WixComponentGuidNamespace, String.Concat(guid, instanceId));
204
+ instanceComponentRow[2] = targetComponentRow[2];
205
+ instanceComponentRow[3] = targetComponentRow[3];
206
+ instanceComponentRow[4] = targetComponentRow[4];
207
+ instanceComponentRow[5] = targetComponentRow[5];
208
+ }
209
+ }
210
+ }
211
+
212
+ // Update the summary information
213
+ var summaryRows = new Dictionary<int, Row>(instanceSummaryInformationTable.Rows.Count);
214
+ foreach (var row in instanceSummaryInformationTable.Rows)
215
+ {
216
+ summaryRows[(int)row[0]] = row;
217
+
218
+ if ((int)SummaryInformation.Transform.UpdatedPlatformAndLanguage == (int)row[0])
219
+ {
220
+ row[1] = targetPlatformAndLanguage;
221
+ }
222
+ else if ((int)SummaryInformation.Transform.ProductCodes == (int)row[0])
223
+ {
224
+ row[1] = String.Concat(targetProductCode, targetProductVersion, ';', productCode, targetProductVersion, ';', targetUpgradeCode);
225
+ }
226
+ else if ((int)SummaryInformation.Transform.ValidationFlags == (int)row[0])
227
+ {
228
+ row[1] = 0;
229
+ }
230
+ else if ((int)SummaryInformation.Transform.Security == (int)row[0])
231
+ {
232
+ row[1] = "4";
233
+ }
234
+ }
235
+
236
+ if (!summaryRows.ContainsKey((int)SummaryInformation.Transform.UpdatedPlatformAndLanguage))
237
+ {
238
+ var summaryRow = instanceSummaryInformationTable.CreateRow(instanceTuple.SourceLineNumbers);
239
+ summaryRow[0] = (int)SummaryInformation.Transform.UpdatedPlatformAndLanguage;
240
+ summaryRow[1] = targetPlatformAndLanguage;
241
+ }
242
+ else if (!summaryRows.ContainsKey((int)SummaryInformation.Transform.ValidationFlags))
243
+ {
244
+ var summaryRow = instanceSummaryInformationTable.CreateRow(instanceTuple.SourceLineNumbers);
245
+ summaryRow[0] = (int)SummaryInformation.Transform.ValidationFlags;
246
+ summaryRow[1] = "0";
247
+ }
248
+ else if (!summaryRows.ContainsKey((int)SummaryInformation.Transform.Security))
249
+ {
250
+ var summaryRow = instanceSummaryInformationTable.CreateRow(instanceTuple.SourceLineNumbers);
251
+ summaryRow[0] = (int)SummaryInformation.Transform.Security;
252
+ summaryRow[1] = "4";
253
+ }
254
+
255
+ this.Output.SubStorages.Add(new SubStorage(instanceId, instanceTransform));
256
+ }
257
+ }
258
+ }
259
+ }
260
+}
src/test/WixToolsetTest.CoreIntegration/MsiFixture.cs
+35
-2
@@ -790,7 +790,7 @@ namespace WixToolsetTest.CoreIntegration
790
}
791
}
792
793
- [Fact(Skip = "Not implemented yet.")]
793
+ [Fact]
794
public void CanBuildInstanceTransform()
795
{
796
var folder = TestData.Get(@"TestData\InstanceTransform");
@@ -813,7 +813,30 @@ namespace WixToolsetTest.CoreIntegration
813
result.AssertSuccess();
814
815
var output = WindowsInstallerData.Load(Path.Combine(intermediateFolder, @"bin\test.wixpdb"), false);
816
- Assert.NotEmpty(output.SubStorages);
816
+ var substorage = output.SubStorages.Single();
817
+ Assert.Equal("I1", substorage.Name);
818
+
819
+ var data = substorage.Data;
820
+ Assert.Equal(new[]
821
+ {
822
+ "_SummaryInformation",
823
+ "Property",
824
+ "Upgrade"
825
+ }, data.Tables.Select(t => t.Name).ToArray());
826
+
827
+ Assert.Equal(new[]
828
+ {
829
+ "INSTANCEPROPERTY\tI1",
830
+ "ProductName\tMsiPackage (Instance 1)",
831
+ }, JoinRows(data.Tables["Property"]));
832
+
833
+ Assert.Equal(new[]
834
+ {
835
+ "{047730A5-30FE-4A62-A520-DA9381B8226A}\t\t1.0.0.0\t1033\t1\t\tWIX_UPGRADE_DETECTED",
836
+ "{047730A5-30FE-4A62-A520-DA9381B8226A}\t\t1.0.0.0\t1033\t1\t0\t0",
837
+ "{047730A5-30FE-4A62-A520-DA9381B8226A}\t1.0.0.0\t\t1033\t2\t\tWIX_DOWNGRADE_DETECTED",
838
+ "{047730A5-30FE-4A62-A520-DA9381B8226A}\t1.0.0.0\t\t1033\t2\t0\t0"
839
+ }, JoinRows(data.Tables["Upgrade"]));
840
}
841
}
842
@@ -850,5 +873,15 @@ namespace WixToolsetTest.CoreIntegration
873
Assert.False(File.Exists(msiPath));
874
}
875
}
876
+
877
+ private static string[] JoinRows(Table table)
878
+ {
879
+ return table.Rows.Select(r => JoinFields(r.Fields)).ToArray();
880
+
881
+ string JoinFields(Field[] fields)
882
+ {
883
+ return String.Join('\t', fields.Select(f => f.ToString()));
884
+ }
885
+ }
886
}
887
}