main
cs 329 lines 16 KB
Raw
1 // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3 namespace WixToolsetTest.CoreIntegration
4 {
5 using System.IO;
6 using System.Linq;
7 using WixInternal.TestSupport;
8 using WixInternal.Core.TestPackage;
9 using WixToolset.Data.WindowsInstaller;
10 using Xunit;
11
12 public class CustomActionFixture
13 {
14 [Fact]
15 public void CanBuildSetProperty()
16 {
17 var folder = TestData.Get("TestData", "SetProperty");
18
19 using (var fs = new DisposableFileSystem())
20 {
21 var baseFolder = fs.GetFolder();
22 var intermediateFolder = Path.Combine(baseFolder, "obj");
23
24 var result = WixRunner.Execute(new[]
25 {
26 "build",
27 Path.Combine(folder, "Package.wxs"),
28 Path.Combine(folder, "PackageComponents.wxs"),
29 "-loc", Path.Combine(folder, "Package.en-us.wxl"),
30 "-bindpath", Path.Combine(folder, "data"),
31 "-intermediateFolder", intermediateFolder,
32 "-o", Path.Combine(baseFolder, @"bin\test.msi")
33 });
34
35 result.AssertSuccess();
36
37 var output = WindowsInstallerData.Load(Path.Combine(baseFolder, "bin", "test.wixpdb"), false);
38 var caRows = output.Tables["CustomAction"].Rows.Single();
39 WixAssert.StringEqual("SetINSTALLLOCATION", caRows.FieldAsString(0));
40 WixAssert.StringEqual("51", caRows.FieldAsString(1));
41 WixAssert.StringEqual("INSTALLLOCATION", caRows.FieldAsString(2));
42 WixAssert.StringEqual("[INSTALLFOLDER]", caRows.FieldAsString(3));
43 }
44 }
45
46 [Fact]
47 public void CannotBuildWhenSetPropertyReferencesMissingAction()
48 {
49 var folder = TestData.Get("TestData", "SetProperty");
50
51 using (var fs = new DisposableFileSystem())
52 {
53 var baseFolder = fs.GetFolder();
54 var intermediateFolder = Path.Combine(baseFolder, "obj");
55
56 var result = WixRunner.Execute(new[]
57 {
58 "build",
59 Path.Combine(folder, "CannotBuildWhenSetPropertyReferencesMissingAction.wxs"),
60 "-bindpath", Path.Combine(folder, "data"),
61 "-intermediateFolder", intermediateFolder,
62 "-o", Path.Combine(baseFolder, @"bin\test.msi")
63 });
64
65 var messages = result.Messages.Select(m => m.ToString()).ToArray();
66 WixAssert.CompareLineByLine(new[]
67 {
68 "The identifier 'WixAction:InstallUISequence/OnlyScheduledInExecuteSequence' could not be found. Ensure you have typed the reference correctly and that all the necessary inputs are provided to the linker."
69 }, messages);
70 }
71 }
72
73 [Fact]
74 public void CanDetectCustomActionCycle()
75 {
76 var folder = TestData.Get(@"TestData");
77
78 using (var fs = new DisposableFileSystem())
79 {
80 var baseFolder = fs.GetFolder();
81 var intermediateFolder = Path.Combine(baseFolder, "obj");
82 var msiPath = Path.Combine(baseFolder, @"bin\test.msi");
83
84 var result = WixRunner.Execute(new[]
85 {
86 "build",
87 Path.Combine(folder, "CustomAction", "CustomActionCycle.wxs"),
88 Path.Combine(folder, "ProductWithComponentGroupRef", "MinimalComponentGroup.wxs"),
89 Path.Combine(folder, "ProductWithComponentGroupRef", "Product.wxs"),
90 "-bindpath", Path.Combine(folder, "SingleFile", "data"),
91 "-intermediateFolder", intermediateFolder,
92 "-o", msiPath
93 });
94
95 Assert.Equal(176, result.ExitCode);
96 WixAssert.StringEqual("The InstallExecuteSequence table contains an action 'Action1' that is scheduled to come before or after action 'Action3', which is also scheduled to come before or after action 'Action1'. Please remove this circular dependency by changing the Before or After attribute for one of the actions.", result.Messages[0].ToString());
97 }
98 }
99
100 [Fact]
101 public void WarnsOnVBScriptCustomAction()
102 {
103 var folder = TestData.Get(@"TestData");
104
105 using (var fs = new DisposableFileSystem())
106 {
107 var baseFolder = fs.GetFolder();
108 var intermediateFolder = Path.Combine(baseFolder, "obj");
109 var msiPath = Path.Combine(baseFolder, @"bin\test.msi");
110
111 var result = WixRunner.Execute(new[]
112 {
113 "build",
114 Path.Combine(folder, "CustomAction", "VBScriptCustomAction.wxs"),
115 Path.Combine(folder, "ProductWithComponentGroupRef", "MinimalComponentGroup.wxs"),
116 Path.Combine(folder, "ProductWithComponentGroupRef", "Product.wxs"),
117 "-bindpath", Path.Combine(folder, "SingleFile", "data"),
118 "-intermediateFolder", intermediateFolder,
119 "-o", msiPath
120 });
121
122 Assert.Equal(1163, result.ExitCode);
123 Assert.Equal(3, result.Messages.Length);
124 Assert.Equal(3, result.Messages.Where(m => m.Id == 1163).Count());
125 }
126 }
127
128 [Fact]
129 public void CanDetectCustomActionCycleWithTail()
130 {
131 var folder = TestData.Get(@"TestData");
132
133 using (var fs = new DisposableFileSystem())
134 {
135 var baseFolder = fs.GetFolder();
136 var intermediateFolder = Path.Combine(baseFolder, "obj");
137 var msiPath = Path.Combine(baseFolder, @"bin\test.msi");
138
139 var result = WixRunner.Execute(new[]
140 {
141 "build",
142 Path.Combine(folder, "CustomAction", "CustomActionCycleWithTail.wxs"),
143 Path.Combine(folder, "ProductWithComponentGroupRef", "MinimalComponentGroup.wxs"),
144 Path.Combine(folder, "ProductWithComponentGroupRef", "Product.wxs"),
145 "-bindpath", Path.Combine(folder, "SingleFile", "data"),
146 "-intermediateFolder", intermediateFolder,
147 "-o", msiPath
148 });
149
150 Assert.Equal(176, result.ExitCode);
151 WixAssert.StringEqual("The InstallExecuteSequence table contains an action 'Action2' that is scheduled to come before or after action 'Action4', which is also scheduled to come before or after action 'Action2'. Please remove this circular dependency by changing the Before or After attribute for one of the actions.", result.Messages[0].ToString());
152 }
153 }
154
155 [Fact]
156 public void CanScheduleCustomActionInModule()
157 {
158 var folder = TestData.Get(@"TestData");
159
160 using (var fs = new DisposableFileSystem())
161 {
162 var baseFolder = fs.GetFolder();
163 var intermediateFolder = Path.Combine(baseFolder, "obj");
164 var msmPath = Path.Combine(baseFolder, "bin", "test.msm");
165
166 var result = WixRunner.Execute(new[]
167 {
168 "build",
169 Path.Combine(folder, "CustomAction", "MsmCustomAction.wxs"),
170 Path.Combine(folder, "CustomAction", "SimpleCustomAction.wxs"),
171 "-bindpath", Path.Combine(folder, ".Data"),
172 "-intermediateFolder", intermediateFolder,
173 "-o", msmPath
174 });
175
176 result.AssertSuccess();
177
178 var rows = Query.QueryDatabase(msmPath, new[] { "CustomAction", "ModuleInstallExecuteSequence" });
179 WixAssert.CompareLineByLine(new[]
180 {
181 "CustomAction:Action1.243FB739_4D05_472F_9CFB_EF6B1017B6DE\t1\tBinary1.243FB739_4D05_472F_9CFB_EF6B1017B6DE\tEntryPoint1\t",
182 "ModuleInstallExecuteSequence:Action1.243FB739_4D05_472F_9CFB_EF6B1017B6DE\t\tInstallFiles\t1\t",
183 "ModuleInstallExecuteSequence:CreateFolders\t3700\t\t\t",
184 "ModuleInstallExecuteSequence:InstallFiles\t4000\t\t\t",
185 "ModuleInstallExecuteSequence:RemoveFiles\t3500\t\t\t",
186 "ModuleInstallExecuteSequence:RemoveFolders\t3600\t\t\t"
187 }, rows);
188 }
189 }
190
191 [Fact]
192 public void CanScheduleSetPropertyInModule()
193 {
194 var folder = TestData.Get(@"TestData");
195
196 using (var fs = new DisposableFileSystem())
197 {
198 var baseFolder = fs.GetFolder();
199 var intermediateFolder = Path.Combine(baseFolder, "obj");
200 var msmPath = Path.Combine(baseFolder, "bin", "test.msm");
201
202 var result = WixRunner.Execute(new[]
203 {
204 "build",
205 Path.Combine(folder, "SetProperty", "MsmSetProperty.wxs"),
206 "-bindpath", Path.Combine(folder, "SetProperty", "data"),
207 "-intermediateFolder", intermediateFolder,
208 "-o", msmPath
209 });
210
211 result.AssertSuccess();
212
213 var rows = Query.QueryDatabase(msmPath, new[] { "CustomAction", "ModuleInstallExecuteSequence" });
214 WixAssert.CompareLineByLine(new[]
215 {
216 "CustomAction:SetINSTALLLOCATION.243FB739_4D05_472F_9CFB_EF6B1017B6DE\t51\tINSTALLLOCATION.243FB739_4D05_472F_9CFB_EF6B1017B6DE\t[INSTALLFOLDER.243FB739_4D05_472F_9CFB_EF6B1017B6DE]\t",
217 "ModuleInstallExecuteSequence:CostFinalize\t1000\t\t\t",
218 "ModuleInstallExecuteSequence:CreateFolders\t3700\t\t\t",
219 "ModuleInstallExecuteSequence:InstallFiles\t4000\t\t\t",
220 "ModuleInstallExecuteSequence:RemoveFiles\t3500\t\t\t",
221 "ModuleInstallExecuteSequence:RemoveFolders\t3600\t\t\t","" +
222 "ModuleInstallExecuteSequence:SetINSTALLLOCATION.243FB739_4D05_472F_9CFB_EF6B1017B6DE\t\tCostFinalize\t1\t"
223 }, rows);
224 }
225 }
226
227 [Fact]
228 public void PopulatesCustomActionTable()
229 {
230 var folder = TestData.Get(@"TestData");
231
232 using (var fs = new DisposableFileSystem())
233 {
234 var baseFolder = fs.GetFolder();
235 var intermediateFolder = Path.Combine(baseFolder, "obj");
236 var msiPath = Path.Combine(baseFolder, @"bin\test.msi");
237
238 var result = WixRunner.Execute(new[]
239 {
240 "build",
241 Path.Combine(folder, "CustomAction", "UnscheduledCustomAction.wxs"),
242 Path.Combine(folder, "ProductWithComponentGroupRef", "MinimalComponentGroup.wxs"),
243 Path.Combine(folder, "ProductWithComponentGroupRef", "Product.wxs"),
244 "-bindpath", Path.Combine(folder, "SingleFile", "data"),
245 "-intermediateFolder", intermediateFolder,
246 "-o", msiPath
247 });
248
249 result.AssertSuccess();
250
251 Assert.True(File.Exists(msiPath));
252 var results = Query.QueryDatabase(msiPath, new[] {
253 "ActionText",
254 "AdminExecuteSequence",
255 "AdminUISequence",
256 "AdvtExecuteSequence",
257 "Binary",
258 "CustomAction",
259 "InstallExecuteSequence",
260 "InstallUISequence",
261 "Property",
262 }).Where(x => !x.StartsWith("Property:") || x.StartsWith("Property:MsiHiddenProperties\t")).ToArray();
263 WixAssert.CompareLineByLine(new[]
264 {
265 "ActionText:CustomAction2\tProgess2Text\t",
266 "AdminExecuteSequence:CostFinalize\t\t1000",
267 "AdminExecuteSequence:CostInitialize\t\t800",
268 "AdminExecuteSequence:CustomAction2\t\t801",
269 "AdminExecuteSequence:FileCost\t\t900",
270 "AdminExecuteSequence:InstallAdminPackage\t\t3900",
271 "AdminExecuteSequence:InstallFiles\t\t4000",
272 "AdminExecuteSequence:InstallFinalize\t\t6600",
273 "AdminExecuteSequence:InstallInitialize\t\t1500",
274 "AdminExecuteSequence:InstallValidate\t\t1400",
275 "AdminUISequence:CostFinalize\t\t1000",
276 "AdminUISequence:CostInitialize\t\t800",
277 "AdminUISequence:CustomAction2\t\t801",
278 "AdminUISequence:ExecuteAction\t\t1300",
279 "AdminUISequence:FileCost\t\t900",
280 "AdvtExecuteSequence:CostFinalize\t\t1000",
281 "AdvtExecuteSequence:CostInitialize\t\t800",
282 "AdvtExecuteSequence:CustomAction2\t\t801",
283 "AdvtExecuteSequence:InstallFinalize\t\t6600",
284 "AdvtExecuteSequence:InstallInitialize\t\t1500",
285 "AdvtExecuteSequence:InstallValidate\t\t1400",
286 "AdvtExecuteSequence:PublishFeatures\t\t6300",
287 "AdvtExecuteSequence:PublishProduct\t\t6400",
288 "Binary:Binary1\t[Binary data]",
289 "CustomAction:CustomAction1\t1\tBinary1\tInvalidEntryPoint\t",
290 "CustomAction:CustomAction2\t51\tTestAdvtExecuteSequenceProperty\t1\t",
291 "CustomAction:CustomActionWithHiddenTarget\t9217\tBinary1\tInvalidEntryPoint\t",
292 "CustomAction:DiscardOptimismAllBeingsWhoProceed\t19\t\tAbandon hope all ye who enter here.\t",
293 "InstallExecuteSequence:CostFinalize\t\t1000",
294 "InstallExecuteSequence:CostInitialize\t\t800",
295 "InstallExecuteSequence:CreateFolders\t\t3700",
296 "InstallExecuteSequence:CustomAction2\t\t801",
297 "InstallExecuteSequence:FileCost\t\t900",
298 "InstallExecuteSequence:FindRelatedProducts\t\t25",
299 "InstallExecuteSequence:InstallFiles\t\t4000",
300 "InstallExecuteSequence:InstallFinalize\t\t6600",
301 "InstallExecuteSequence:InstallInitialize\t\t1500",
302 "InstallExecuteSequence:InstallValidate\t\t1400",
303 "InstallExecuteSequence:LaunchConditions\t\t100",
304 "InstallExecuteSequence:MigrateFeatureStates\t\t1200",
305 "InstallExecuteSequence:ProcessComponents\t\t1600",
306 "InstallExecuteSequence:PublishFeatures\t\t6300",
307 "InstallExecuteSequence:PublishProduct\t\t6400",
308 "InstallExecuteSequence:RegisterProduct\t\t6100",
309 "InstallExecuteSequence:RegisterUser\t\t6000",
310 "InstallExecuteSequence:RemoveExistingProducts\t\t1401",
311 "InstallExecuteSequence:RemoveFiles\t\t3500",
312 "InstallExecuteSequence:RemoveFolders\t\t3600",
313 "InstallExecuteSequence:UnpublishFeatures\t\t1800",
314 "InstallExecuteSequence:ValidateProductID\t\t700",
315 "InstallUISequence:CostFinalize\t\t1000",
316 "InstallUISequence:CostInitialize\t\t800",
317 "InstallUISequence:CustomAction2\t\t801",
318 "InstallUISequence:ExecuteAction\t\t1300",
319 "InstallUISequence:FileCost\t\t900",
320 "InstallUISequence:FindRelatedProducts\t\t25",
321 "InstallUISequence:LaunchConditions\t\t100",
322 "InstallUISequence:MigrateFeatureStates\t\t1200",
323 "InstallUISequence:ValidateProductID\t\t700",
324 "Property:MsiHiddenProperties\tCustomActionWithHiddenTarget",
325 }, results);
326 }
327 }
328 }
329 }