aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2019-12-11 19:34:47 +1100
committerSean Hall <r.sean.hall@gmail.com>2019-12-11 20:10:40 +1000
commit62352fabd541aaa9d0a2c957c4bdd4b9c682df9c (patch)
tree941513045cb644553af582fc0722c853793a90dd /src
parentca118d0123624e4e1523eeb7a54eb56364d5876e (diff)
downloadwix-62352fabd541aaa9d0a2c957c4bdd4b9c682df9c.tar.gz
wix-62352fabd541aaa9d0a2c957c4bdd4b9c682df9c.tar.bz2
wix-62352fabd541aaa9d0a2c957c4bdd4b9c682df9c.zip
Import files from BootstrapperCore repo.
Diffstat (limited to 'src')
-rw-r--r--src/WixToolset.Mba.Core/BaseBootstrapperApplicationFactory.cs16
-rw-r--r--src/WixToolset.Mba.Core/BootstrapperApplication.cs1591
-rw-r--r--src/WixToolset.Mba.Core/BootstrapperApplicationData.cs63
-rw-r--r--src/WixToolset.Mba.Core/BootstrapperApplicationFactory.cs86
-rw-r--r--src/WixToolset.Mba.Core/BootstrapperApplicationFactoryAttribute.cs35
-rw-r--r--src/WixToolset.Mba.Core/BootstrapperCommand.cs107
-rw-r--r--src/WixToolset.Mba.Core/BootstrapperSectionGroup.cs29
-rw-r--r--src/WixToolset.Mba.Core/BundleInfo.cs67
-rw-r--r--src/WixToolset.Mba.Core/Engine.cs516
-rw-r--r--src/WixToolset.Mba.Core/EventArgs.cs1903
-rw-r--r--src/WixToolset.Mba.Core/Exceptions.cs145
-rw-r--r--src/WixToolset.Mba.Core/HostSection.cs47
-rw-r--r--src/WixToolset.Mba.Core/IBootstrapperApplicationData.cs12
-rw-r--r--src/WixToolset.Mba.Core/IBootstrapperApplicationFactory.cs52
-rw-r--r--src/WixToolset.Mba.Core/IBootstrapperCommand.cs63
-rw-r--r--src/WixToolset.Mba.Core/IBundleInfo.cs16
-rw-r--r--src/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs65
-rw-r--r--src/WixToolset.Mba.Core/IEngine.cs176
-rw-r--r--src/WixToolset.Mba.Core/IPackageInfo.cs20
-rw-r--r--src/WixToolset.Mba.Core/IVariables.cs27
-rw-r--r--src/WixToolset.Mba.Core/NativeMethods.cs37
-rw-r--r--src/WixToolset.Mba.Core/PackageInfo.cs181
-rw-r--r--src/WixToolset.Mba.Core/SupportedFrameworkElement.cs47
-rw-r--r--src/WixToolset.Mba.Core/SupportedFrameworkElementCollection.cs36
-rw-r--r--src/WixToolset.Mba.Core/WixToolset.BootstrapperCore.config26
-rw-r--r--src/balutil/inc/IBootstrapperApplicationFactory.h14
26 files changed, 5377 insertions, 0 deletions
diff --git a/src/WixToolset.Mba.Core/BaseBootstrapperApplicationFactory.cs b/src/WixToolset.Mba.Core/BaseBootstrapperApplicationFactory.cs
new file mode 100644
index 00000000..e9b60929
--- /dev/null
+++ b/src/WixToolset.Mba.Core/BaseBootstrapperApplicationFactory.cs
@@ -0,0 +1,16 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 public abstract class BaseBootstrapperApplicationFactory : IBootstrapperApplicationFactory
6 {
7 public IBootstrapperApplication Create(IBootstrapperEngine pEngine, ref Command command)
8 {
9 IEngine engine = new Engine(pEngine);
10 IBootstrapperCommand bootstrapperCommand = command.GetBootstrapperCommand();
11 return this.Create(engine, bootstrapperCommand);
12 }
13
14 protected abstract IBootstrapperApplication Create(IEngine engine, IBootstrapperCommand bootstrapperCommand);
15 }
16}
diff --git a/src/WixToolset.Mba.Core/BootstrapperApplication.cs b/src/WixToolset.Mba.Core/BootstrapperApplication.cs
new file mode 100644
index 00000000..c08a60c7
--- /dev/null
+++ b/src/WixToolset.Mba.Core/BootstrapperApplication.cs
@@ -0,0 +1,1591 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.Runtime.InteropServices;
7 using System.Threading;
8
9 /// <summary>
10 /// The default bootstrapper application.
11 /// </summary>
12 [ClassInterface(ClassInterfaceType.None)]
13 public abstract class BootstrapperApplication : MarshalByRefObject, IDefaultBootstrapperApplication
14 {
15 /// <summary>
16 /// Specifies whether this bootstrapper should run asynchronously. The default is true.
17 /// </summary>
18 protected readonly bool asyncExecution;
19
20 /// <summary>
21 /// Gets the <see cref="IEngine"/> for interaction with the engine.
22 /// </summary>
23 protected readonly IEngine engine;
24
25 private bool applying;
26
27 /// <summary>
28 /// Creates a new instance of the <see cref="BootstrapperApplication"/> class.
29 /// </summary>
30 protected BootstrapperApplication(IEngine engine)
31 {
32 this.engine = engine;
33 this.applying = false;
34 this.asyncExecution = true;
35 }
36
37 /// <summary>
38 /// Fired when the engine is starting up the bootstrapper application.
39 /// </summary>
40 public event EventHandler<StartupEventArgs> Startup;
41
42 /// <summary>
43 /// Fired when the engine is shutting down the bootstrapper application.
44 /// </summary>
45 public event EventHandler<ShutdownEventArgs> Shutdown;
46
47 /// <summary>
48 /// Fired when the system is shutting down or user is logging off.
49 /// </summary>
50 /// <remarks>
51 /// <para>To prevent shutting down or logging off, set <see cref="CancellableHResultEventArgs.Cancel"/> to
52 /// true; otherwise, set it to false.</para>
53 /// <para>By default setup will prevent shutting down or logging off between
54 /// <see cref="BootstrapperApplication.ApplyBegin"/> and <see cref="BootstrapperApplication.ApplyComplete"/>.
55 /// Derivatives can change this behavior by overriding <see cref="BootstrapperApplication.OnSystemShutdown"/>
56 /// or handling <see cref="BootstrapperApplication.SystemShutdown"/>.</para>
57 /// <para>If <see cref="SystemShutdownEventArgs.Reasons"/> contains <see cref="EndSessionReasons.Critical"/>
58 /// the bootstrapper cannot prevent the shutdown and only has a few seconds to save state or perform any other
59 /// critical operations before being closed by the operating system.</para>
60 /// <para>This event may be fired on a different thread.</para>
61 /// </remarks>
62 public event EventHandler<SystemShutdownEventArgs> SystemShutdown;
63
64 /// <summary>
65 /// Fired when the overall detection phase has begun.
66 /// </summary>
67 public event EventHandler<DetectBeginEventArgs> DetectBegin;
68
69 /// <summary>
70 /// Fired when a forward compatible bundle is detected.
71 /// </summary>
72 public event EventHandler<DetectForwardCompatibleBundleEventArgs> DetectForwardCompatibleBundle;
73
74 /// <summary>
75 /// Fired when the update detection phase has begun.
76 /// </summary>
77 public event EventHandler<DetectUpdateBeginEventArgs> DetectUpdateBegin;
78
79 /// <summary>
80 /// Fired when the update detection has found a potential update candidate.
81 /// </summary>
82 public event EventHandler<DetectUpdateEventArgs> DetectUpdate;
83
84 /// <summary>
85 /// Fired when the update detection phase has completed.
86 /// </summary>
87 public event EventHandler<DetectUpdateCompleteEventArgs> DetectUpdateComplete;
88
89 /// <summary>
90 /// Fired when a related bundle has been detected for a bundle.
91 /// </summary>
92 public event EventHandler<DetectRelatedBundleEventArgs> DetectRelatedBundle;
93
94 /// <summary>
95 /// Fired when the detection for a specific package has begun.
96 /// </summary>
97 public event EventHandler<DetectPackageBeginEventArgs> DetectPackageBegin;
98
99 /// <summary>
100 /// Fired when a package was not detected but a package using the same provider key was.
101 /// </summary>
102 public event EventHandler<DetectCompatibleMsiPackageEventArgs> DetectCompatibleMsiPackage;
103
104 /// <summary>
105 /// Fired when a related MSI package has been detected for a package.
106 /// </summary>
107 public event EventHandler<DetectRelatedMsiPackageEventArgs> DetectRelatedMsiPackage;
108
109 /// <summary>
110 /// Fired when an MSP package detects a target MSI has been detected.
111 /// </summary>
112 public event EventHandler<DetectTargetMsiPackageEventArgs> DetectTargetMsiPackage;
113
114 /// <summary>
115 /// Fired when a feature in an MSI package has been detected.
116 /// </summary>
117 public event EventHandler<DetectMsiFeatureEventArgs> DetectMsiFeature;
118
119 /// <summary>
120 /// Fired when the detection for a specific package has completed.
121 /// </summary>
122 public event EventHandler<DetectPackageCompleteEventArgs> DetectPackageComplete;
123
124 /// <summary>
125 /// Fired when the detection phase has completed.
126 /// </summary>
127 public event EventHandler<DetectCompleteEventArgs> DetectComplete;
128
129 /// <summary>
130 /// Fired when the engine has begun planning the installation.
131 /// </summary>
132 public event EventHandler<PlanBeginEventArgs> PlanBegin;
133
134 /// <summary>
135 /// Fired when the engine has begun planning for a related bundle.
136 /// </summary>
137 public event EventHandler<PlanRelatedBundleEventArgs> PlanRelatedBundle;
138
139 /// <summary>
140 /// Fired when the engine has begun planning the installation of a specific package.
141 /// </summary>
142 public event EventHandler<PlanPackageBeginEventArgs> PlanPackageBegin;
143
144 /// <summary>
145 /// Fired when the engine plans a new, compatible package using the same provider key.
146 /// </summary>
147 public event EventHandler<PlanCompatibleMsiPackageBeginEventArgs> PlanCompatibleMsiPackageBegin;
148
149 /// <summary>
150 /// Fired when the engine has completed planning the installation of a specific package.
151 /// </summary>
152 public event EventHandler<PlanCompatibleMsiPackageCompleteEventArgs> PlanCompatibleMsiPackageComplete;
153
154 /// <summary>
155 /// Fired when the engine is about to plan the target MSI of a MSP package.
156 /// </summary>
157 public event EventHandler<PlanTargetMsiPackageEventArgs> PlanTargetMsiPackage;
158
159 /// <summary>
160 /// Fired when the engine is about to plan a feature in an MSI package.
161 /// </summary>
162 public event EventHandler<PlanMsiFeatureEventArgs> PlanMsiFeature;
163
164 /// <summary>
165 /// Fired when the engine has completed planning the installation of a specific package.
166 /// </summary>
167 public event EventHandler<PlanPackageCompleteEventArgs> PlanPackageComplete;
168
169 /// <summary>
170 /// Fired when the engine has completed planning the installation.
171 /// </summary>
172 public event EventHandler<PlanCompleteEventArgs> PlanComplete;
173
174 /// <summary>
175 /// Fired when the engine has begun installing the bundle.
176 /// </summary>
177 public event EventHandler<ApplyBeginEventArgs> ApplyBegin;
178
179 /// <summary>
180 /// Fired when the engine is about to start the elevated process.
181 /// </summary>
182 public event EventHandler<ElevateBeginEventArgs> ElevateBegin;
183
184 /// <summary>
185 /// Fired when the engine has completed starting the elevated process.
186 /// </summary>
187 public event EventHandler<ElevateCompleteEventArgs> ElevateComplete;
188
189 /// <summary>
190 /// Fired when the engine has changed progress for the bundle installation.
191 /// </summary>
192 public event EventHandler<ProgressEventArgs> Progress;
193
194 /// <summary>
195 /// Fired when the engine has encountered an error.
196 /// </summary>
197 public event EventHandler<ErrorEventArgs> Error;
198
199 /// <summary>
200 /// Fired when the engine has begun registering the location and visibility of the bundle.
201 /// </summary>
202 public event EventHandler<RegisterBeginEventArgs> RegisterBegin;
203
204 /// <summary>
205 /// Fired when the engine has completed registering the location and visibility of the bundle.
206 /// </summary>
207 public event EventHandler<RegisterCompleteEventArgs> RegisterComplete;
208
209 /// <summary>
210 /// Fired when the engine has begun removing the registration for the location and visibility of the bundle.
211 /// </summary>
212 public event EventHandler<UnregisterBeginEventArgs> UnregisterBegin;
213
214 /// <summary>
215 /// Fired when the engine has completed removing the registration for the location and visibility of the bundle.
216 /// </summary>
217 public event EventHandler<UnregisterCompleteEventArgs> UnregisterComplete;
218
219 /// <summary>
220 /// Fired when the engine has begun caching the installation sources.
221 /// </summary>
222 public event EventHandler<CacheBeginEventArgs> CacheBegin;
223
224 /// <summary>
225 /// Fired when the engine has begun caching a specific package.
226 /// </summary>
227 public event EventHandler<CachePackageBeginEventArgs> CachePackageBegin;
228
229 /// <summary>
230 /// Fired when the engine has begun acquiring the installation sources.
231 /// </summary>
232 public event EventHandler<CacheAcquireBeginEventArgs> CacheAcquireBegin;
233
234 /// <summary>
235 /// Fired when the engine has progress acquiring the installation sources.
236 /// </summary>
237 public event EventHandler<CacheAcquireProgressEventArgs> CacheAcquireProgress;
238
239 /// <summary>
240 /// Fired by the engine to allow the BA to change the source
241 /// using <see cref="M:Engine.SetLocalSource"/> or <see cref="M:Engine.SetDownloadSource"/>.
242 /// </summary>
243 public event EventHandler<ResolveSourceEventArgs> ResolveSource;
244
245 /// <summary>
246 /// Fired when the engine has completed the acquisition of the installation sources.
247 /// </summary>
248 public event EventHandler<CacheAcquireCompleteEventArgs> CacheAcquireComplete;
249
250 /// <summary>
251 /// Fired when the engine begins the verification of the acquired installation sources.
252 /// </summary>
253 public event EventHandler<CacheVerifyBeginEventArgs> CacheVerifyBegin;
254
255 /// <summary>
256 /// Fired when the engine complete the verification of the acquired installation sources.
257 /// </summary>
258 public event EventHandler<CacheVerifyCompleteEventArgs> CacheVerifyComplete;
259
260 /// <summary>
261 /// Fired when the engine has completed caching a specific package.
262 /// </summary>
263 public event EventHandler<CachePackageCompleteEventArgs> CachePackageComplete;
264
265 /// <summary>
266 /// Fired after the engine has cached the installation sources.
267 /// </summary>
268 public event EventHandler<CacheCompleteEventArgs> CacheComplete;
269
270 /// <summary>
271 /// Fired when the engine has begun installing packages.
272 /// </summary>
273 public event EventHandler<ExecuteBeginEventArgs> ExecuteBegin;
274
275 /// <summary>
276 /// Fired when the engine has begun installing a specific package.
277 /// </summary>
278 public event EventHandler<ExecutePackageBeginEventArgs> ExecutePackageBegin;
279
280 /// <summary>
281 /// Fired when the engine executes one or more patches targeting a product.
282 /// </summary>
283 public event EventHandler<ExecutePatchTargetEventArgs> ExecutePatchTarget;
284
285 /// <summary>
286 /// Fired when Windows Installer sends an installation message.
287 /// </summary>
288 public event EventHandler<ExecuteMsiMessageEventArgs> ExecuteMsiMessage;
289
290 /// <summary>
291 /// Fired when Windows Installer sends a files in use installation message.
292 /// </summary>
293 public event EventHandler<ExecuteFilesInUseEventArgs> ExecuteFilesInUse;
294
295 /// <summary>
296 /// Fired when the engine has completed installing a specific package.
297 /// </summary>
298 public event EventHandler<ExecutePackageCompleteEventArgs> ExecutePackageComplete;
299
300 /// <summary>
301 /// Fired when the engine has completed installing packages.
302 /// </summary>
303 public event EventHandler<ExecuteCompleteEventArgs> ExecuteComplete;
304
305 /// <summary>
306 /// Fired when the engine has completed installing the bundle.
307 /// </summary>
308 public event EventHandler<ApplyCompleteEventArgs> ApplyComplete;
309
310 /// <summary>
311 /// Fired by the engine while executing on payload.
312 /// </summary>
313 public event EventHandler<ExecuteProgressEventArgs> ExecuteProgress;
314
315 /// <summary>
316 /// Fired when the engine is about to launch the preapproved executable.
317 /// </summary>
318 public event EventHandler<LaunchApprovedExeBeginArgs> LaunchApprovedExeBegin;
319
320 /// <summary>
321 /// Fired when the engine has completed launching the preapproved executable.
322 /// </summary>
323 public event EventHandler<LaunchApprovedExeCompleteArgs> LaunchApprovedExeComplete;
324
325 /// <summary>
326 /// Entry point that is called when the bootstrapper application is ready to run.
327 /// </summary>
328 protected abstract void Run();
329
330 /// <summary>
331 /// Called by the engine on startup of the bootstrapper application.
332 /// </summary>
333 /// <param name="args">Additional arguments for this event.</param>
334 protected virtual void OnStartup(StartupEventArgs args)
335 {
336 EventHandler<StartupEventArgs> handler = this.Startup;
337 if (null != handler)
338 {
339 handler(this, args);
340 }
341
342 if (this.asyncExecution)
343 {
344 this.engine.Log(LogLevel.Verbose, "Creating BA thread to run asynchronously.");
345 Thread uiThread = new Thread(this.Run);
346 uiThread.Name = "UIThread";
347 uiThread.SetApartmentState(ApartmentState.STA);
348 uiThread.Start();
349 }
350 else
351 {
352 this.engine.Log(LogLevel.Verbose, "Creating BA thread to run synchronously.");
353 this.Run();
354 }
355 }
356
357 /// <summary>
358 /// Called by the engine to uninitialize the BA.
359 /// </summary>
360 /// <param name="args">Additional arguments for this event.</param>
361 protected virtual void OnShutdown(ShutdownEventArgs args)
362 {
363 EventHandler<ShutdownEventArgs> handler = this.Shutdown;
364 if (null != handler)
365 {
366 handler(this, args);
367 }
368 }
369
370 /// <summary>
371 /// Called when the system is shutting down or the user is logging off.
372 /// </summary>
373 /// <param name="args">Additional arguments for this event.</param>
374 /// <remarks>
375 /// <para>To prevent shutting down or logging off, set <see cref="CancellableHResultEventArgs.Cancel"/> to
376 /// true; otherwise, set it to false.</para>
377 /// <para>By default setup will prevent shutting down or logging off between
378 /// <see cref="BootstrapperApplication.ApplyBegin"/> and <see cref="BootstrapperApplication.ApplyComplete"/>.
379 /// Derivatives can change this behavior by overriding <see cref="BootstrapperApplication.OnSystemShutdown"/>
380 /// or handling <see cref="BootstrapperApplication.SystemShutdown"/>.</para>
381 /// <para>If <see cref="SystemShutdownEventArgs.Reasons"/> contains <see cref="EndSessionReasons.Critical"/>
382 /// the bootstrapper cannot prevent the shutdown and only has a few seconds to save state or perform any other
383 /// critical operations before being closed by the operating system.</para>
384 /// <para>This method may be called on a different thread.</para>
385 /// </remarks>
386 protected virtual void OnSystemShutdown(SystemShutdownEventArgs args)
387 {
388 EventHandler<SystemShutdownEventArgs> handler = this.SystemShutdown;
389 if (null != handler)
390 {
391 handler(this, args);
392 }
393 else if (null != args)
394 {
395 // Allow requests to shut down when critical or not applying.
396 bool critical = EndSessionReasons.Critical == (EndSessionReasons.Critical & args.Reasons);
397 args.Cancel = !critical && this.applying;
398 }
399 }
400
401 /// <summary>
402 /// Called when the overall detection phase has begun.
403 /// </summary>
404 /// <param name="args">Additional arguments for this event.</param>
405 protected virtual void OnDetectBegin(DetectBeginEventArgs args)
406 {
407 EventHandler<DetectBeginEventArgs> handler = this.DetectBegin;
408 if (null != handler)
409 {
410 handler(this, args);
411 }
412 }
413
414 /// <summary>
415 /// Called when the update detection phase has begun.
416 /// </summary>
417 /// <param name="args">Additional arguments for this event.</param>
418 protected virtual void OnDetectForwardCompatibleBundle(DetectForwardCompatibleBundleEventArgs args)
419 {
420 EventHandler<DetectForwardCompatibleBundleEventArgs> handler = this.DetectForwardCompatibleBundle;
421 if (null != handler)
422 {
423 handler(this, args);
424 }
425 }
426
427 /// <summary>
428 /// Called when the update detection phase has begun.
429 /// </summary>
430 /// <param name="args">Additional arguments for this event.</param>
431 protected virtual void OnDetectUpdateBegin(DetectUpdateBeginEventArgs args)
432 {
433 EventHandler<DetectUpdateBeginEventArgs> handler = this.DetectUpdateBegin;
434 if (null != handler)
435 {
436 handler(this, args);
437 }
438 }
439
440 /// <summary>
441 /// Fired when the update detection has found a potential update candidate.
442 /// </summary>
443 /// <param name="args">Additional arguments for this event.</param>
444 protected virtual void OnDetectUpdate(DetectUpdateEventArgs args)
445 {
446 EventHandler<DetectUpdateEventArgs> handler = this.DetectUpdate;
447 if (null != handler)
448 {
449 handler(this, args);
450 }
451 }
452
453 /// <summary>
454 /// Called when the update detection phase has completed.
455 /// </summary>
456 /// <param name="args">Additional arguments for this event.</param>
457 protected virtual void OnDetectUpdateComplete(DetectUpdateCompleteEventArgs args)
458 {
459 EventHandler<DetectUpdateCompleteEventArgs> handler = this.DetectUpdateComplete;
460 if (null != handler)
461 {
462 handler(this, args);
463 }
464 }
465
466 /// <summary>
467 /// Called when a related bundle has been detected for a bundle.
468 /// </summary>
469 /// <param name="args">Additional arguments for this event.</param>
470 protected virtual void OnDetectRelatedBundle(DetectRelatedBundleEventArgs args)
471 {
472 EventHandler<DetectRelatedBundleEventArgs> handler = this.DetectRelatedBundle;
473 if (null != handler)
474 {
475 handler(this, args);
476 }
477 }
478
479 /// <summary>
480 /// Called when the detection for a specific package has begun.
481 /// </summary>
482 /// <param name="args">Additional arguments for this event.</param>
483 protected virtual void OnDetectPackageBegin(DetectPackageBeginEventArgs args)
484 {
485 EventHandler<DetectPackageBeginEventArgs> handler = this.DetectPackageBegin;
486 if (null != handler)
487 {
488 handler(this, args);
489 }
490 }
491
492 /// <summary>
493 /// Called when a package was not detected but a package using the same provider key was.
494 /// </summary>
495 /// <param name="args">Additional arguments for this event.</param>
496 protected virtual void OnDetectCompatibleMsiPackage(DetectCompatibleMsiPackageEventArgs args)
497 {
498 EventHandler<DetectCompatibleMsiPackageEventArgs> handler = this.DetectCompatibleMsiPackage;
499 if (null != handler)
500 {
501 handler(this, args);
502 }
503 }
504
505 /// <summary>
506 /// Called when a related MSI package has been detected for a package.
507 /// </summary>
508 /// <param name="args">Additional arguments for this event.</param>
509 protected virtual void OnDetectRelatedMsiPackage(DetectRelatedMsiPackageEventArgs args)
510 {
511 EventHandler<DetectRelatedMsiPackageEventArgs> handler = this.DetectRelatedMsiPackage;
512 if (null != handler)
513 {
514 handler(this, args);
515 }
516 }
517
518 /// <summary>
519 /// Called when an MSP package detects a target MSI has been detected.
520 /// </summary>
521 /// <param name="args">Additional arguments for this event.</param>
522 protected virtual void OnDetectTargetMsiPackage(DetectTargetMsiPackageEventArgs args)
523 {
524 EventHandler<DetectTargetMsiPackageEventArgs> handler = this.DetectTargetMsiPackage;
525 if (null != handler)
526 {
527 handler(this, args);
528 }
529 }
530
531 /// <summary>
532 /// Called when an MSI feature has been detected for a package.
533 /// </summary>
534 /// <param name="args">Additional arguments for this event.</param>
535 protected virtual void OnDetectMsiFeature(DetectMsiFeatureEventArgs args)
536 {
537 EventHandler<DetectMsiFeatureEventArgs> handler = this.DetectMsiFeature;
538 if (null != handler)
539 {
540 handler(this, args);
541 }
542 }
543
544 /// <summary>
545 /// Called when the detection for a specific package has completed.
546 /// </summary>
547 /// <param name="args">Additional arguments for this event.</param>
548 protected virtual void OnDetectPackageComplete(DetectPackageCompleteEventArgs args)
549 {
550 EventHandler<DetectPackageCompleteEventArgs> handler = this.DetectPackageComplete;
551 if (null != handler)
552 {
553 handler(this, args);
554 }
555 }
556
557 /// <summary>
558 /// Called when the detection phase has completed.
559 /// </summary>
560 /// <param name="args">Additional arguments for this event.</param>
561 protected virtual void OnDetectComplete(DetectCompleteEventArgs args)
562 {
563 EventHandler<DetectCompleteEventArgs> handler = this.DetectComplete;
564 if (null != handler)
565 {
566 handler(this, args);
567 }
568 }
569
570 /// <summary>
571 /// Called when the engine has begun planning the installation.
572 /// </summary>
573 /// <param name="args">Additional arguments for this event.</param>
574 protected virtual void OnPlanBegin(PlanBeginEventArgs args)
575 {
576 EventHandler<PlanBeginEventArgs> handler = this.PlanBegin;
577 if (null != handler)
578 {
579 handler(this, args);
580 }
581 }
582
583 /// <summary>
584 /// Called when the engine has begun planning for a prior bundle.
585 /// </summary>
586 /// <param name="args">Additional arguments for this event.</param>
587 protected virtual void OnPlanRelatedBundle(PlanRelatedBundleEventArgs args)
588 {
589 EventHandler<PlanRelatedBundleEventArgs> handler = this.PlanRelatedBundle;
590 if (null != handler)
591 {
592 handler(this, args);
593 }
594 }
595
596 /// <summary>
597 /// Called when the engine has begun planning the installation of a specific package.
598 /// </summary>
599 /// <param name="args">Additional arguments for this event.</param>
600 protected virtual void OnPlanPackageBegin(PlanPackageBeginEventArgs args)
601 {
602 EventHandler<PlanPackageBeginEventArgs> handler = this.PlanPackageBegin;
603 if (null != handler)
604 {
605 handler(this, args);
606 }
607 }
608
609 /// <summary>
610 /// Called when the engine plans a new, compatible package using the same provider key.
611 /// </summary>
612 /// <param name="args">Additional arguments for this event.</param>
613 protected virtual void OnPlanCompatibleMsiPackageBegin(PlanCompatibleMsiPackageBeginEventArgs args)
614 {
615 EventHandler<PlanCompatibleMsiPackageBeginEventArgs> handler = this.PlanCompatibleMsiPackageBegin;
616 if (null != handler)
617 {
618 handler(this, args);
619 }
620 }
621
622 /// <summary>
623 /// Called when the engine has completed planning the installation of a specific package.
624 /// </summary>
625 /// <param name="args">Additional arguments for this event.</param>
626 protected virtual void OnPlanCompatibleMsiPackageComplete(PlanCompatibleMsiPackageCompleteEventArgs args)
627 {
628 EventHandler<PlanCompatibleMsiPackageCompleteEventArgs> handler = this.PlanCompatibleMsiPackageComplete;
629 if (null != handler)
630 {
631 handler(this, args);
632 }
633 }
634
635 /// <summary>
636 /// Called when the engine is about to plan the target MSI of a MSP package.
637 /// </summary>
638 /// <param name="args">Additional arguments for this event.</param>
639 protected virtual void OnPlanTargetMsiPackage(PlanTargetMsiPackageEventArgs args)
640 {
641 EventHandler<PlanTargetMsiPackageEventArgs> handler = this.PlanTargetMsiPackage;
642 if (null != handler)
643 {
644 handler(this, args);
645 }
646 }
647
648 /// <summary>
649 /// Called when the engine is about to plan an MSI feature of a specific package.
650 /// </summary>
651 /// <param name="args">Additional arguments for this event.</param>
652 protected virtual void OnPlanMsiFeature(PlanMsiFeatureEventArgs args)
653 {
654 EventHandler<PlanMsiFeatureEventArgs> handler = this.PlanMsiFeature;
655 if (null != handler)
656 {
657 handler(this, args);
658 }
659 }
660
661 /// <summary>
662 /// Called when then engine has completed planning the installation of a specific package.
663 /// </summary>
664 /// <param name="args">Additional arguments for this event.</param>
665 protected virtual void OnPlanPackageComplete(PlanPackageCompleteEventArgs args)
666 {
667 EventHandler<PlanPackageCompleteEventArgs> handler = this.PlanPackageComplete;
668 if (null != handler)
669 {
670 handler(this, args);
671 }
672 }
673
674 /// <summary>
675 /// Called when the engine has completed planning the installation.
676 /// </summary>
677 /// <param name="args">Additional arguments for this event.</param>
678 protected virtual void OnPlanComplete(PlanCompleteEventArgs args)
679 {
680 EventHandler<PlanCompleteEventArgs> handler = this.PlanComplete;
681 if (null != handler)
682 {
683 handler(this, args);
684 }
685 }
686
687 /// <summary>
688 /// Called when the engine has begun installing the bundle.
689 /// </summary>
690 /// <param name="args">Additional arguments for this event.</param>
691 protected virtual void OnApplyBegin(ApplyBeginEventArgs args)
692 {
693 EventHandler<ApplyBeginEventArgs> handler = this.ApplyBegin;
694 if (null != handler)
695 {
696 handler(this, args);
697 }
698 }
699
700 /// <summary>
701 /// Called when the engine is about to start the elevated process.
702 /// </summary>
703 /// <param name="args">Additional arguments for this event.</param>
704 protected virtual void OnElevateBegin(ElevateBeginEventArgs args)
705 {
706 EventHandler<ElevateBeginEventArgs> handler = this.ElevateBegin;
707 if (null != handler)
708 {
709 handler(this, args);
710 }
711 }
712
713 /// <summary>
714 /// Called when the engine has completed starting the elevated process.
715 /// </summary>
716 /// <param name="args">Additional arguments for this event.</param>
717 protected virtual void OnElevateComplete(ElevateCompleteEventArgs args)
718 {
719 EventHandler<ElevateCompleteEventArgs> handler = this.ElevateComplete;
720 if (null != handler)
721 {
722 handler(this, args);
723 }
724 }
725
726 /// <summary>
727 /// Called when the engine has changed progress for the bundle installation.
728 /// </summary>
729 /// <param name="args">Additional arguments for this event.</param>
730 protected virtual void OnProgress(ProgressEventArgs args)
731 {
732 EventHandler<ProgressEventArgs> handler = this.Progress;
733 if (null != handler)
734 {
735 handler(this, args);
736 }
737 }
738
739 /// <summary>
740 /// Called when the engine has encountered an error.
741 /// </summary>
742 /// <param name="args">Additional arguments for this event.</param>
743 protected virtual void OnError(ErrorEventArgs args)
744 {
745 EventHandler<ErrorEventArgs> handler = this.Error;
746 if (null != handler)
747 {
748 handler(this, args);
749 }
750 }
751
752 /// <summary>
753 /// Called when the engine has begun registering the location and visibility of the bundle.
754 /// </summary>
755 /// <param name="args">Additional arguments for this event.</param>
756 protected virtual void OnRegisterBegin(RegisterBeginEventArgs args)
757 {
758 EventHandler<RegisterBeginEventArgs> handler = this.RegisterBegin;
759 if (null != handler)
760 {
761 handler(this, args);
762 }
763 }
764
765 /// <summary>
766 /// Called when the engine has completed registering the location and visilibity of the bundle.
767 /// </summary>
768 /// <param name="args">Additional arguments for this event.</param>
769 protected virtual void OnRegisterComplete(RegisterCompleteEventArgs args)
770 {
771 EventHandler<RegisterCompleteEventArgs> handler = this.RegisterComplete;
772 if (null != handler)
773 {
774 handler(this, args);
775 }
776 }
777
778 /// <summary>
779 /// Called when the engine has begun removing the registration for the location and visibility of the bundle.
780 /// </summary>
781 /// <param name="args">Additional arguments for this event.</param>
782 protected virtual void OnUnregisterBegin(UnregisterBeginEventArgs args)
783 {
784 EventHandler<UnregisterBeginEventArgs> handler = this.UnregisterBegin;
785 if (null != handler)
786 {
787 handler(this, args);
788 }
789 }
790
791 /// <summary>
792 /// Called when the engine has completed removing the registration for the location and visibility of the bundle.
793 /// </summary>
794 /// <param name="args">Additional arguments for this event.</param>
795 protected virtual void OnUnregisterComplete(UnregisterCompleteEventArgs args)
796 {
797 EventHandler<UnregisterCompleteEventArgs> handler = this.UnregisterComplete;
798 if (null != handler)
799 {
800 handler(this, args);
801 }
802 }
803
804 /// <summary>
805 /// Called when the engine begins to cache the installation sources.
806 /// </summary>
807 /// <param name="args"></param>
808 protected virtual void OnCacheBegin(CacheBeginEventArgs args)
809 {
810 EventHandler<CacheBeginEventArgs> handler = this.CacheBegin;
811 if (null != handler)
812 {
813 handler(this, args);
814 }
815 }
816
817 /// <summary>
818 /// Called by the engine when it begins to cache a specific package.
819 /// </summary>
820 /// <param name="args"></param>
821 protected virtual void OnCachePackageBegin(CachePackageBeginEventArgs args)
822 {
823 EventHandler<CachePackageBeginEventArgs> handler = this.CachePackageBegin;
824 if (null != handler)
825 {
826 handler(this, args);
827 }
828 }
829
830 /// <summary>
831 /// Called when the engine begins to cache the container or payload.
832 /// </summary>
833 /// <param name="args"></param>
834 protected virtual void OnCacheAcquireBegin(CacheAcquireBeginEventArgs args)
835 {
836 EventHandler<CacheAcquireBeginEventArgs> handler = this.CacheAcquireBegin;
837 if (null != handler)
838 {
839 handler(this, args);
840 }
841 }
842
843 /// <summary>
844 /// Called when the engine has progressed on caching the container or payload.
845 /// </summary>
846 /// <param name="args"></param>
847 protected virtual void OnCacheAcquireProgress(CacheAcquireProgressEventArgs args)
848 {
849 EventHandler<CacheAcquireProgressEventArgs> handler = this.CacheAcquireProgress;
850 if (null != handler)
851 {
852 handler(this, args);
853 }
854 }
855
856 /// <summary>
857 /// Called by the engine to allow the BA to change the source
858 /// using <see cref="M:Engine.SetLocalSource"/> or <see cref="M:Engine.SetDownloadSource"/>.
859 /// </summary>
860 /// <param name="args">Additional arguments for this event.</param>
861 protected virtual void OnResolveSource(ResolveSourceEventArgs args)
862 {
863 EventHandler<ResolveSourceEventArgs> handler = this.ResolveSource;
864 if (null != handler)
865 {
866 handler(this, args);
867 }
868 }
869
870 /// <summary>
871 /// Called when the engine completes caching of the container or payload.
872 /// </summary>
873 /// <param name="args"></param>
874 protected virtual void OnCacheAcquireComplete(CacheAcquireCompleteEventArgs args)
875 {
876 EventHandler<CacheAcquireCompleteEventArgs> handler = this.CacheAcquireComplete;
877 if (null != handler)
878 {
879 handler(this, args);
880 }
881 }
882
883 /// <summary>
884 /// Called when the engine has started verify the payload.
885 /// </summary>
886 /// <param name="args"></param>
887 protected virtual void OnCacheVerifyBegin(CacheVerifyBeginEventArgs args)
888 {
889 EventHandler<CacheVerifyBeginEventArgs> handler = this.CacheVerifyBegin;
890 if (null != handler)
891 {
892 handler(this, args);
893 }
894 }
895
896 /// <summary>
897 /// Called when the engine completes verification of the payload.
898 /// </summary>
899 /// <param name="args"></param>
900 protected virtual void OnCacheVerifyComplete(CacheVerifyCompleteEventArgs args)
901 {
902 EventHandler<CacheVerifyCompleteEventArgs> handler = this.CacheVerifyComplete;
903 if (null != handler)
904 {
905 handler(this, args);
906 }
907 }
908
909 /// <summary>
910 /// Called when the engine completes caching a specific package.
911 /// </summary>
912 /// <param name="args"></param>
913 protected virtual void OnCachePackageComplete(CachePackageCompleteEventArgs args)
914 {
915 EventHandler<CachePackageCompleteEventArgs> handler = this.CachePackageComplete;
916 if (null != handler)
917 {
918 handler(this, args);
919 }
920 }
921
922 /// <summary>
923 /// Called after the engine has cached the installation sources.
924 /// </summary>
925 /// <param name="args">Additional arguments for this event.</param>
926 protected virtual void OnCacheComplete(CacheCompleteEventArgs args)
927 {
928 EventHandler<CacheCompleteEventArgs> handler = this.CacheComplete;
929 if (null != handler)
930 {
931 handler(this, args);
932 }
933 }
934
935 /// <summary>
936 /// Called when the engine has begun installing packages.
937 /// </summary>
938 /// <param name="args">Additional arguments for this event.</param>
939 protected virtual void OnExecuteBegin(ExecuteBeginEventArgs args)
940 {
941 EventHandler<ExecuteBeginEventArgs> handler = this.ExecuteBegin;
942 if (null != handler)
943 {
944 handler(this, args);
945 }
946 }
947
948 /// <summary>
949 /// Called when the engine has begun installing a specific package.
950 /// </summary>
951 /// <param name="args">Additional arguments for this event.</param>
952 protected virtual void OnExecutePackageBegin(ExecutePackageBeginEventArgs args)
953 {
954 EventHandler<ExecutePackageBeginEventArgs> handler = this.ExecutePackageBegin;
955 if (null != handler)
956 {
957 handler(this, args);
958 }
959 }
960
961 /// <summary>
962 /// Called when the engine executes one or more patches targeting a product.
963 /// </summary>
964 /// <param name="args">Additional arguments for this event.</param>
965 protected virtual void OnExecutePatchTarget(ExecutePatchTargetEventArgs args)
966 {
967 EventHandler<ExecutePatchTargetEventArgs> handler = this.ExecutePatchTarget;
968 if (null != handler)
969 {
970 handler(this, args);
971 }
972 }
973
974 /// <summary>
975 /// Called when Windows Installer sends an installation message.
976 /// </summary>
977 /// <param name="args">Additional arguments for this event.</param>
978 protected virtual void OnExecuteMsiMessage(ExecuteMsiMessageEventArgs args)
979 {
980 EventHandler<ExecuteMsiMessageEventArgs> handler = this.ExecuteMsiMessage;
981 if (null != handler)
982 {
983 handler(this, args);
984 }
985 }
986
987 /// <summary>
988 /// Called when Windows Installer sends a file in use installation message.
989 /// </summary>
990 /// <param name="args">Additional arguments for this event.</param>
991 protected virtual void OnExecuteFilesInUse(ExecuteFilesInUseEventArgs args)
992 {
993 EventHandler<ExecuteFilesInUseEventArgs> handler = this.ExecuteFilesInUse;
994 if (null != handler)
995 {
996 handler(this, args);
997 }
998 }
999
1000 /// <summary>
1001 /// Called when the engine has completed installing a specific package.
1002 /// </summary>
1003 /// <param name="args">Additional arguments for this event.</param>
1004 protected virtual void OnExecutePackageComplete(ExecutePackageCompleteEventArgs args)
1005 {
1006 EventHandler<ExecutePackageCompleteEventArgs> handler = this.ExecutePackageComplete;
1007 if (null != handler)
1008 {
1009 handler(this, args);
1010 }
1011 }
1012
1013 /// <summary>
1014 /// Called when the engine has completed installing packages.
1015 /// </summary>
1016 /// <param name="args">Additional arguments for this event.</param>
1017 protected virtual void OnExecuteComplete(ExecuteCompleteEventArgs args)
1018 {
1019 EventHandler<ExecuteCompleteEventArgs> handler = this.ExecuteComplete;
1020 if (null != handler)
1021 {
1022 handler(this, args);
1023 }
1024 }
1025
1026 /// <summary>
1027 /// Called when the engine has completed installing the bundle.
1028 /// </summary>
1029 /// <param name="args">Additional arguments for this event.</param>
1030 protected virtual void OnApplyComplete(ApplyCompleteEventArgs args)
1031 {
1032 EventHandler<ApplyCompleteEventArgs> handler = this.ApplyComplete;
1033 if (null != handler)
1034 {
1035 handler(this, args);
1036 }
1037 }
1038
1039 /// <summary>
1040 /// Called by the engine while executing on payload.
1041 /// </summary>
1042 /// <param name="args">Additional arguments for this event.</param>
1043 protected virtual void OnExecuteProgress(ExecuteProgressEventArgs args)
1044 {
1045 EventHandler<ExecuteProgressEventArgs> handler = this.ExecuteProgress;
1046 if (null != handler)
1047 {
1048 handler(this, args);
1049 }
1050 }
1051
1052 /// <summary>
1053 /// Called by the engine before trying to launch the preapproved executable.
1054 /// </summary>
1055 /// <param name="args">Additional arguments for this event.</param>
1056 protected virtual void OnLaunchApprovedExeBegin(LaunchApprovedExeBeginArgs args)
1057 {
1058 EventHandler<LaunchApprovedExeBeginArgs> handler = this.LaunchApprovedExeBegin;
1059 if (null != handler)
1060 {
1061 handler(this, args);
1062 }
1063 }
1064
1065 /// <summary>
1066 /// Called by the engine after trying to launch the preapproved executable.
1067 /// </summary>
1068 /// <param name="args">Additional arguments for this event.</param>
1069 protected virtual void OnLaunchApprovedExeComplete(LaunchApprovedExeCompleteArgs args)
1070 {
1071 EventHandler<LaunchApprovedExeCompleteArgs> handler = this.LaunchApprovedExeComplete;
1072 if (null != handler)
1073 {
1074 handler(this, args);
1075 }
1076 }
1077
1078 #region IBootstrapperApplication Members
1079
1080 int IBootstrapperApplication.OnStartup()
1081 {
1082 StartupEventArgs args = new StartupEventArgs();
1083 this.OnStartup(args);
1084
1085 return args.HResult;
1086 }
1087
1088 int IBootstrapperApplication.OnShutdown(ref BOOTSTRAPPER_SHUTDOWN_ACTION action)
1089 {
1090 ShutdownEventArgs args = new ShutdownEventArgs(action);
1091 this.OnShutdown(args);
1092
1093 action = args.Action;
1094 return args.HResult;
1095 }
1096
1097 int IBootstrapperApplication.OnSystemShutdown(EndSessionReasons dwEndSession, ref bool fCancel)
1098 {
1099 SystemShutdownEventArgs args = new SystemShutdownEventArgs(dwEndSession, fCancel);
1100 this.OnSystemShutdown(args);
1101
1102 fCancel = args.Cancel;
1103 return args.HResult;
1104 }
1105
1106 int IBootstrapperApplication.OnDetectBegin(bool fInstalled, int cPackages, ref bool fCancel)
1107 {
1108 DetectBeginEventArgs args = new DetectBeginEventArgs(fInstalled, cPackages, fCancel);
1109 this.OnDetectBegin(args);
1110
1111 fCancel = args.Cancel;
1112 return args.HResult;
1113 }
1114
1115 int IBootstrapperApplication.OnDetectForwardCompatibleBundle(string wzBundleId, RelationType relationType, string wzBundleTag, bool fPerMachine, long version, ref bool fCancel, ref bool fIgnoreBundle)
1116 {
1117 DetectForwardCompatibleBundleEventArgs args = new DetectForwardCompatibleBundleEventArgs(wzBundleId, relationType, wzBundleTag, fPerMachine, version, fCancel, fIgnoreBundle);
1118 this.OnDetectForwardCompatibleBundle(args);
1119
1120 fCancel = args.Cancel;
1121 fIgnoreBundle = args.IgnoreBundle;
1122 return args.HResult;
1123 }
1124
1125 int IBootstrapperApplication.OnDetectUpdateBegin(string wzUpdateLocation, ref bool fCancel, ref bool fSkip)
1126 {
1127 DetectUpdateBeginEventArgs args = new DetectUpdateBeginEventArgs(wzUpdateLocation, fCancel, fSkip);
1128 this.OnDetectUpdateBegin(args);
1129
1130 fCancel = args.Cancel;
1131 fSkip = args.Skip;
1132 return args.HResult;
1133 }
1134
1135 int IBootstrapperApplication.OnDetectUpdate(string wzUpdateLocation, long dw64Size, long dw64Version, string wzTitle, string wzSummary, string wzContentType, string wzContent, ref bool fCancel, ref bool fStopProcessingUpdates)
1136 {
1137 DetectUpdateEventArgs args = new DetectUpdateEventArgs(wzUpdateLocation, dw64Size, dw64Version, wzTitle, wzSummary, wzContentType, wzContent, fCancel, fStopProcessingUpdates);
1138 this.OnDetectUpdate(args);
1139
1140 fCancel = args.Cancel;
1141 fStopProcessingUpdates = args.StopProcessingUpdates;
1142 return args.HResult;
1143 }
1144
1145 int IBootstrapperApplication.OnDetectUpdateComplete(int hrStatus, ref bool fIgnoreError)
1146 {
1147 DetectUpdateCompleteEventArgs args = new DetectUpdateCompleteEventArgs(hrStatus, fIgnoreError);
1148 this.OnDetectUpdateComplete(args);
1149
1150 fIgnoreError = args.IgnoreError;
1151 return args.HResult;
1152 }
1153
1154 int IBootstrapperApplication.OnDetectRelatedBundle(string wzProductCode, RelationType relationType, string wzBundleTag, bool fPerMachine, long version, RelatedOperation operation, ref bool fCancel)
1155 {
1156 DetectRelatedBundleEventArgs args = new DetectRelatedBundleEventArgs(wzProductCode, relationType, wzBundleTag, fPerMachine, version, operation, fCancel);
1157 this.OnDetectRelatedBundle(args);
1158
1159 fCancel = args.Cancel;
1160 return args.HResult;
1161 }
1162
1163 int IBootstrapperApplication.OnDetectPackageBegin(string wzPackageId, ref bool fCancel)
1164 {
1165 DetectPackageBeginEventArgs args = new DetectPackageBeginEventArgs(wzPackageId, fCancel);
1166 this.OnDetectPackageBegin(args);
1167
1168 fCancel = args.Cancel;
1169 return args.HResult;
1170 }
1171
1172 int IBootstrapperApplication.OnDetectCompatibleMsiPackage(string wzPackageId, string wzCompatiblePackageId, long dw64CompatiblePackageVersion, ref bool fCancel)
1173 {
1174 DetectCompatibleMsiPackageEventArgs args = new DetectCompatibleMsiPackageEventArgs(wzPackageId, wzCompatiblePackageId, dw64CompatiblePackageVersion, fCancel);
1175 this.OnDetectCompatibleMsiPackage(args);
1176
1177 fCancel = args.Cancel;
1178 return args.HResult;
1179 }
1180
1181 int IBootstrapperApplication.OnDetectRelatedMsiPackage(string wzPackageId, string wzUpgradeCode, string wzProductCode, bool fPerMachine, long version, RelatedOperation operation, ref bool fCancel)
1182 {
1183 DetectRelatedMsiPackageEventArgs args = new DetectRelatedMsiPackageEventArgs(wzPackageId, wzUpgradeCode, wzProductCode, fPerMachine, version, operation, fCancel);
1184 this.OnDetectRelatedMsiPackage(args);
1185
1186 fCancel = args.Cancel;
1187 return args.HResult;
1188 }
1189
1190 int IBootstrapperApplication.OnDetectTargetMsiPackage(string wzPackageId, string wzProductCode, PackageState patchState, ref bool fCancel)
1191 {
1192 DetectTargetMsiPackageEventArgs args = new DetectTargetMsiPackageEventArgs(wzPackageId, wzProductCode, patchState, fCancel);
1193 this.OnDetectTargetMsiPackage(args);
1194
1195 fCancel = args.Cancel;
1196 return args.HResult;
1197 }
1198
1199 int IBootstrapperApplication.OnDetectMsiFeature(string wzPackageId, string wzFeatureId, FeatureState state, ref bool fCancel)
1200 {
1201 DetectMsiFeatureEventArgs args = new DetectMsiFeatureEventArgs(wzPackageId, wzFeatureId, state, fCancel);
1202 this.OnDetectMsiFeature(args);
1203
1204 fCancel = args.Cancel;
1205 return args.HResult;
1206 }
1207
1208 int IBootstrapperApplication.OnDetectPackageComplete(string wzPackageId, int hrStatus, PackageState state)
1209 {
1210 DetectPackageCompleteEventArgs args = new DetectPackageCompleteEventArgs(wzPackageId, hrStatus, state);
1211 this.OnDetectPackageComplete(args);
1212
1213 return args.HResult;
1214 }
1215
1216 int IBootstrapperApplication.OnDetectComplete(int hrStatus)
1217 {
1218 DetectCompleteEventArgs args = new DetectCompleteEventArgs(hrStatus);
1219 this.OnDetectComplete(args);
1220
1221 return args.HResult;
1222 }
1223
1224 int IBootstrapperApplication.OnPlanBegin(int cPackages, ref bool fCancel)
1225 {
1226 PlanBeginEventArgs args = new PlanBeginEventArgs(cPackages, fCancel);
1227 this.OnPlanBegin(args);
1228
1229 fCancel = args.Cancel;
1230 return args.HResult;
1231 }
1232
1233 int IBootstrapperApplication.OnPlanRelatedBundle(string wzBundleId, RequestState recommendedState, ref RequestState pRequestedState, ref bool fCancel)
1234 {
1235 PlanRelatedBundleEventArgs args = new PlanRelatedBundleEventArgs(wzBundleId, recommendedState, pRequestedState, fCancel);
1236 this.OnPlanRelatedBundle(args);
1237
1238 pRequestedState = args.State;
1239 fCancel = args.Cancel;
1240 return args.HResult;
1241 }
1242
1243 int IBootstrapperApplication.OnPlanPackageBegin(string wzPackageId, RequestState recommendedState, ref RequestState pRequestedState, ref bool fCancel)
1244 {
1245 PlanPackageBeginEventArgs args = new PlanPackageBeginEventArgs(wzPackageId, recommendedState, pRequestedState, fCancel);
1246 this.OnPlanPackageBegin(args);
1247
1248 pRequestedState = args.State;
1249 fCancel = args.Cancel;
1250 return args.HResult;
1251 }
1252
1253 int IBootstrapperApplication.OnPlanCompatibleMsiPackageBegin(string wzPackageId, string wzCompatiblePackageId, long dw64CompatiblePackageVersion, RequestState recommendedState, ref RequestState pRequestedState, ref bool fCancel)
1254 {
1255 PlanCompatibleMsiPackageBeginEventArgs args = new PlanCompatibleMsiPackageBeginEventArgs(wzPackageId, wzCompatiblePackageId, dw64CompatiblePackageVersion, recommendedState, pRequestedState, fCancel);
1256 this.OnPlanCompatibleMsiPackageBegin(args);
1257
1258 pRequestedState = args.State;
1259 fCancel = args.Cancel;
1260 return args.HResult;
1261 }
1262
1263 int IBootstrapperApplication.OnPlanCompatibleMsiPackageComplete(string wzPackageId, string wzCompatiblePackageId, int hrStatus, PackageState state, RequestState requested, ActionState execute, ActionState rollback)
1264 {
1265 PlanCompatibleMsiPackageCompleteEventArgs args = new PlanCompatibleMsiPackageCompleteEventArgs(wzPackageId, wzCompatiblePackageId, hrStatus, state, requested, execute, rollback);
1266 this.OnPlanCompatibleMsiPackageComplete(args);
1267
1268 return args.HResult;
1269 }
1270
1271 int IBootstrapperApplication.OnPlanTargetMsiPackage(string wzPackageId, string wzProductCode, RequestState recommendedState, ref RequestState pRequestedState, ref bool fCancel)
1272 {
1273 PlanTargetMsiPackageEventArgs args = new PlanTargetMsiPackageEventArgs(wzPackageId, wzProductCode, recommendedState, pRequestedState, fCancel);
1274 this.OnPlanTargetMsiPackage(args);
1275
1276 pRequestedState = args.State;
1277 fCancel = args.Cancel;
1278 return args.HResult;
1279 }
1280
1281 int IBootstrapperApplication.OnPlanMsiFeature(string wzPackageId, string wzFeatureId, FeatureState recommendedState, ref FeatureState pRequestedState, ref bool fCancel)
1282 {
1283 PlanMsiFeatureEventArgs args = new PlanMsiFeatureEventArgs(wzPackageId, wzFeatureId, recommendedState, pRequestedState, fCancel);
1284 this.OnPlanMsiFeature(args);
1285
1286 pRequestedState = args.State;
1287 fCancel = args.Cancel;
1288 return args.HResult;
1289 }
1290
1291 int IBootstrapperApplication.OnPlanPackageComplete(string wzPackageId, int hrStatus, PackageState state, RequestState requested, ActionState execute, ActionState rollback)
1292 {
1293 var args = new PlanPackageCompleteEventArgs(wzPackageId, hrStatus, state, requested, execute, rollback);
1294 this.OnPlanPackageComplete(args);
1295
1296 return args.HResult;
1297 }
1298
1299 int IBootstrapperApplication.OnPlanComplete(int hrStatus)
1300 {
1301 PlanCompleteEventArgs args = new PlanCompleteEventArgs(hrStatus);
1302 this.OnPlanComplete(args);
1303
1304 return args.HResult;
1305 }
1306
1307 int IBootstrapperApplication.OnApplyBegin(int dwPhaseCount, ref bool fCancel)
1308 {
1309 this.applying = true;
1310
1311 ApplyBeginEventArgs args = new ApplyBeginEventArgs(dwPhaseCount, fCancel);
1312 this.OnApplyBegin(args);
1313
1314 fCancel = args.Cancel;
1315 return args.HResult;
1316 }
1317
1318 int IBootstrapperApplication.OnElevateBegin(ref bool fCancel)
1319 {
1320 ElevateBeginEventArgs args = new ElevateBeginEventArgs(fCancel);
1321 this.OnElevateBegin(args);
1322
1323 fCancel = args.Cancel;
1324 return args.HResult;
1325 }
1326
1327 int IBootstrapperApplication.OnElevateComplete(int hrStatus)
1328 {
1329 ElevateCompleteEventArgs args = new ElevateCompleteEventArgs(hrStatus);
1330 this.OnElevateComplete(args);
1331
1332 return args.HResult;
1333 }
1334
1335 int IBootstrapperApplication.OnProgress(int dwProgressPercentage, int dwOverallPercentage, ref bool fCancel)
1336 {
1337 ProgressEventArgs args = new ProgressEventArgs(dwProgressPercentage, dwOverallPercentage, fCancel);
1338 this.OnProgress(args);
1339
1340 fCancel = args.Cancel;
1341 return args.HResult;
1342 }
1343
1344 int IBootstrapperApplication.OnError(ErrorType errorType, string wzPackageId, int dwCode, string wzError, int dwUIHint, int cData, string[] rgwzData, Result nRecommendation, ref Result pResult)
1345 {
1346 ErrorEventArgs args = new ErrorEventArgs(errorType, wzPackageId, dwCode, wzError, dwUIHint, rgwzData, nRecommendation, pResult);
1347 this.OnError(args);
1348
1349 pResult = args.Result;
1350 return args.HResult;
1351 }
1352
1353 int IBootstrapperApplication.OnRegisterBegin(ref bool fCancel)
1354 {
1355 RegisterBeginEventArgs args = new RegisterBeginEventArgs(fCancel);
1356 this.OnRegisterBegin(args);
1357
1358 fCancel = args.Cancel;
1359 return args.HResult;
1360 }
1361
1362 int IBootstrapperApplication.OnRegisterComplete(int hrStatus)
1363 {
1364 RegisterCompleteEventArgs args = new RegisterCompleteEventArgs(hrStatus);
1365 this.OnRegisterComplete(args);
1366
1367 return args.HResult;
1368 }
1369
1370 int IBootstrapperApplication.OnCacheBegin(ref bool fCancel)
1371 {
1372 CacheBeginEventArgs args = new CacheBeginEventArgs(fCancel);
1373 this.OnCacheBegin(args);
1374
1375 fCancel = args.Cancel;
1376 return args.HResult;
1377 }
1378
1379 int IBootstrapperApplication.OnCachePackageBegin(string wzPackageId, int cCachePayloads, long dw64PackageCacheSize, ref bool fCancel)
1380 {
1381 CachePackageBeginEventArgs args = new CachePackageBeginEventArgs(wzPackageId, cCachePayloads, dw64PackageCacheSize, fCancel);
1382 this.OnCachePackageBegin(args);
1383
1384 fCancel = args.Cancel;
1385 return args.HResult;
1386 }
1387
1388 int IBootstrapperApplication.OnCacheAcquireBegin(string wzPackageOrContainerId, string wzPayloadId, CacheOperation operation, string wzSource, ref bool fCancel)
1389 {
1390 CacheAcquireBeginEventArgs args = new CacheAcquireBeginEventArgs(wzPackageOrContainerId, wzPayloadId, operation, wzSource, fCancel);
1391 this.OnCacheAcquireBegin(args);
1392
1393 fCancel = args.Cancel;
1394 return args.HResult;
1395 }
1396
1397 int IBootstrapperApplication.OnCacheAcquireProgress(string wzPackageOrContainerId, string wzPayloadId, long dw64Progress, long dw64Total, int dwOverallPercentage, ref bool fCancel)
1398 {
1399 CacheAcquireProgressEventArgs args = new CacheAcquireProgressEventArgs(wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage, fCancel);
1400 this.OnCacheAcquireProgress(args);
1401
1402 fCancel = args.Cancel;
1403 return args.HResult;
1404 }
1405
1406 int IBootstrapperApplication.OnResolveSource(string wzPackageOrContainerId, string wzPayloadId, string wzLocalSource, string wzDownloadSource, BOOTSTRAPPER_RESOLVESOURCE_ACTION recommendation, ref BOOTSTRAPPER_RESOLVESOURCE_ACTION action, ref bool fCancel)
1407 {
1408 ResolveSourceEventArgs args = new ResolveSourceEventArgs(wzPackageOrContainerId, wzPayloadId, wzLocalSource, wzDownloadSource, action, recommendation, fCancel);
1409 this.OnResolveSource(args);
1410
1411 action = args.Action;
1412 fCancel = args.Cancel;
1413 return args.HResult;
1414 }
1415
1416 int IBootstrapperApplication.OnCacheAcquireComplete(string wzPackageOrContainerId, string wzPayloadId, int hrStatus, BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION recommendation, ref BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION action)
1417 {
1418 CacheAcquireCompleteEventArgs args = new CacheAcquireCompleteEventArgs(wzPackageOrContainerId, wzPayloadId, hrStatus, recommendation, action);
1419 this.OnCacheAcquireComplete(args);
1420
1421 action = args.Action;
1422 return args.HResult;
1423 }
1424
1425 int IBootstrapperApplication.OnCacheVerifyBegin(string wzPackageId, string wzPayloadId, ref bool fCancel)
1426 {
1427 CacheVerifyBeginEventArgs args = new CacheVerifyBeginEventArgs(wzPackageId, wzPayloadId, fCancel);
1428 this.OnCacheVerifyBegin(args);
1429
1430 fCancel = args.Cancel;
1431 return args.HResult;
1432 }
1433
1434 int IBootstrapperApplication.OnCacheVerifyComplete(string wzPackageId, string wzPayloadId, int hrStatus, BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION recommendation, ref BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action)
1435 {
1436 CacheVerifyCompleteEventArgs args = new CacheVerifyCompleteEventArgs(wzPackageId, wzPayloadId, hrStatus, recommendation, action);
1437 this.OnCacheVerifyComplete(args);
1438
1439 action = args.Action;
1440 return args.HResult;
1441 }
1442
1443 int IBootstrapperApplication.OnCachePackageComplete(string wzPackageId, int hrStatus, BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION recommendation, ref BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION action)
1444 {
1445 CachePackageCompleteEventArgs args = new CachePackageCompleteEventArgs(wzPackageId, hrStatus, recommendation, action);
1446 this.OnCachePackageComplete(args);
1447
1448 action = args.Action;
1449 return args.HResult;
1450 }
1451
1452 int IBootstrapperApplication.OnCacheComplete(int hrStatus)
1453 {
1454 CacheCompleteEventArgs args = new CacheCompleteEventArgs(hrStatus);
1455 this.OnCacheComplete(args);
1456
1457 return args.HResult;
1458 }
1459
1460 int IBootstrapperApplication.OnExecuteBegin(int cExecutingPackages, ref bool fCancel)
1461 {
1462 ExecuteBeginEventArgs args = new ExecuteBeginEventArgs(cExecutingPackages, fCancel);
1463 this.OnExecuteBegin(args);
1464
1465 args.Cancel = fCancel;
1466 return args.HResult;
1467 }
1468
1469 int IBootstrapperApplication.OnExecutePackageBegin(string wzPackageId, bool fExecute, ref bool fCancel)
1470 {
1471 ExecutePackageBeginEventArgs args = new ExecutePackageBeginEventArgs(wzPackageId, fExecute, fCancel);
1472 this.OnExecutePackageBegin(args);
1473
1474 fCancel = args.Cancel;
1475 return args.HResult;
1476 }
1477
1478 int IBootstrapperApplication.OnExecutePatchTarget(string wzPackageId, string wzTargetProductCode, ref bool fCancel)
1479 {
1480 ExecutePatchTargetEventArgs args = new ExecutePatchTargetEventArgs(wzPackageId, wzTargetProductCode, fCancel);
1481 this.OnExecutePatchTarget(args);
1482
1483 fCancel = args.Cancel;
1484 return args.HResult;
1485 }
1486
1487 int IBootstrapperApplication.OnExecuteProgress(string wzPackageId, int dwProgressPercentage, int dwOverallPercentage, ref bool fCancel)
1488 {
1489 ExecuteProgressEventArgs args = new ExecuteProgressEventArgs(wzPackageId, dwProgressPercentage, dwOverallPercentage, fCancel);
1490 this.OnExecuteProgress(args);
1491
1492 fCancel = args.Cancel;
1493 return args.HResult;
1494 }
1495
1496 int IBootstrapperApplication.OnExecuteMsiMessage(string wzPackageId, InstallMessage messageType, int dwUIHint, string wzMessage, int cData, string[] rgwzData, Result nRecommendation, ref Result pResult)
1497 {
1498 ExecuteMsiMessageEventArgs args = new ExecuteMsiMessageEventArgs(wzPackageId, messageType, dwUIHint, wzMessage, rgwzData, nRecommendation, pResult);
1499 this.OnExecuteMsiMessage(args);
1500
1501 pResult = args.Result;
1502 return args.HResult;
1503 }
1504
1505 int IBootstrapperApplication.OnExecuteFilesInUse(string wzPackageId, int cFiles, string[] rgwzFiles, Result nRecommendation, ref Result pResult)
1506 {
1507 ExecuteFilesInUseEventArgs args = new ExecuteFilesInUseEventArgs(wzPackageId, rgwzFiles, nRecommendation, pResult);
1508 this.OnExecuteFilesInUse(args);
1509
1510 pResult = args.Result;
1511 return args.HResult;
1512 }
1513
1514 int IBootstrapperApplication.OnExecutePackageComplete(string wzPackageId, int hrStatus, ApplyRestart restart, BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION recommendation, ref BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION pAction)
1515 {
1516 ExecutePackageCompleteEventArgs args = new ExecutePackageCompleteEventArgs(wzPackageId, hrStatus, restart, recommendation, pAction);
1517 this.OnExecutePackageComplete(args);
1518
1519 pAction = args.Action;
1520 return args.HResult;
1521 }
1522
1523 int IBootstrapperApplication.OnExecuteComplete(int hrStatus)
1524 {
1525 ExecuteCompleteEventArgs args = new ExecuteCompleteEventArgs(hrStatus);
1526 this.OnExecuteComplete(args);
1527
1528 return args.HResult;
1529 }
1530
1531 int IBootstrapperApplication.OnUnregisterBegin(ref bool fCancel)
1532 {
1533 UnregisterBeginEventArgs args = new UnregisterBeginEventArgs(fCancel);
1534 this.OnUnregisterBegin(args);
1535
1536 fCancel = args.Cancel;
1537 return args.HResult;
1538 }
1539
1540 int IBootstrapperApplication.OnUnregisterComplete(int hrStatus)
1541 {
1542 UnregisterCompleteEventArgs args = new UnregisterCompleteEventArgs(hrStatus);
1543 this.OnUnregisterComplete(args);
1544
1545 return args.HResult;
1546 }
1547
1548 int IBootstrapperApplication.OnApplyComplete(int hrStatus, ApplyRestart restart, BOOTSTRAPPER_APPLYCOMPLETE_ACTION recommendation, ref BOOTSTRAPPER_APPLYCOMPLETE_ACTION pAction)
1549 {
1550 ApplyCompleteEventArgs args = new ApplyCompleteEventArgs(hrStatus, restart, recommendation, pAction);
1551 this.OnApplyComplete(args);
1552
1553 this.applying = false;
1554
1555 pAction = args.Action;
1556 return args.HResult;
1557 }
1558
1559 int IBootstrapperApplication.OnLaunchApprovedExeBegin(ref bool fCancel)
1560 {
1561 LaunchApprovedExeBeginArgs args = new LaunchApprovedExeBeginArgs(fCancel);
1562 this.OnLaunchApprovedExeBegin(args);
1563
1564 fCancel = args.Cancel;
1565 return args.HResult;
1566 }
1567
1568 int IBootstrapperApplication.OnLaunchApprovedExeComplete(int hrStatus, int processId)
1569 {
1570 LaunchApprovedExeCompleteArgs args = new LaunchApprovedExeCompleteArgs(hrStatus, processId);
1571 this.OnLaunchApprovedExeComplete(args);
1572
1573 return args.HResult;
1574 }
1575
1576 int IBootstrapperApplication.BAProc(BOOTSTRAPPER_APPLICATION_MESSAGE message, IntPtr pvArgs, IntPtr pvResults, IntPtr pvContext)
1577 {
1578 switch (message)
1579 {
1580 default:
1581 return NativeMethods.E_NOTIMPL;
1582 }
1583 }
1584
1585 void IBootstrapperApplication.BAProcFallback(BOOTSTRAPPER_APPLICATION_MESSAGE message, IntPtr pvArgs, IntPtr pvResults, ref int phr, IntPtr pvContext)
1586 {
1587 }
1588
1589 #endregion
1590 }
1591}
diff --git a/src/WixToolset.Mba.Core/BootstrapperApplicationData.cs b/src/WixToolset.Mba.Core/BootstrapperApplicationData.cs
new file mode 100644
index 00000000..a17f1a05
--- /dev/null
+++ b/src/WixToolset.Mba.Core/BootstrapperApplicationData.cs
@@ -0,0 +1,63 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.IO;
7 using System.Xml.XPath;
8
9 public class BootstrapperApplicationData : IBootstrapperApplicationData
10 {
11 public const string DefaultFileName = "BootstrapperApplicationData.xml";
12 public const string XMLNamespace = "http://wixtoolset.org/schemas/v4/2010/BootstrapperApplicationData";
13
14 public static readonly DirectoryInfo DefaultFolder;
15 public static readonly FileInfo DefaultFile;
16
17 static BootstrapperApplicationData()
18 {
19 DefaultFolder = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
20 DefaultFile = new FileInfo(Path.Combine(DefaultFolder.FullName, DefaultFileName));
21 }
22
23 public FileInfo BADataFile { get; private set; }
24
25 public IBundleInfo Bundle { get; private set; }
26
27 public BootstrapperApplicationData() : this(DefaultFile) { }
28
29 public BootstrapperApplicationData(FileInfo baDataFile)
30 {
31 this.BADataFile = baDataFile;
32
33 using (FileStream fs = this.BADataFile.OpenRead())
34 {
35 this.Bundle = BundleInfo.ParseBundleFromStream(fs);
36 }
37 }
38
39 public static string GetAttribute(XPathNavigator node, string attributeName)
40 {
41 XPathNavigator attribute = node.SelectSingleNode("@" + attributeName);
42
43 if (attribute == null)
44 {
45 return null;
46 }
47
48 return attribute.Value;
49 }
50
51 public static bool? GetYesNoAttribute(XPathNavigator node, string attributeName)
52 {
53 string attributeValue = GetAttribute(node, attributeName);
54
55 if (attributeValue == null)
56 {
57 return null;
58 }
59
60 return attributeValue.Equals("yes", StringComparison.InvariantCulture);
61 }
62 }
63}
diff --git a/src/WixToolset.Mba.Core/BootstrapperApplicationFactory.cs b/src/WixToolset.Mba.Core/BootstrapperApplicationFactory.cs
new file mode 100644
index 00000000..28430bb8
--- /dev/null
+++ b/src/WixToolset.Mba.Core/BootstrapperApplicationFactory.cs
@@ -0,0 +1,86 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.Configuration;
7 using System.Reflection;
8 using System.Runtime.InteropServices;
9
10 /// <summary>
11 /// Entry point for the MBA host to create and return the IBootstrapperApplication implementation to the engine.
12 /// </summary>
13 [ClassInterface(ClassInterfaceType.None)]
14 public sealed class BootstrapperApplicationFactory : MarshalByRefObject, IBootstrapperApplicationFactory
15 {
16 /// <summary>
17 /// Creates a new instance of the <see cref="BootstrapperApplicationFactory"/> class.
18 /// </summary>
19 public BootstrapperApplicationFactory()
20 {
21 }
22
23 /// <summary>
24 /// Loads the bootstrapper application assembly and creates an instance of the IBootstrapperApplication.
25 /// </summary>
26 /// <param name="pEngine">IBootstrapperEngine provided for the bootstrapper application.</param>
27 /// <param name="command">Command line for the bootstrapper application.</param>
28 /// <returns>Bootstrapper application via <see cref="IBootstrapperApplication"/> interface.</returns>
29 /// <exception cref="MissingAttributeException">The bootstrapper application assembly
30 /// does not define the <see cref="BootstrapperApplicationFactoryAttribute"/>.</exception>
31 public IBootstrapperApplication Create(IBootstrapperEngine pEngine, ref Command command)
32 {
33 // Get the wix.boostrapper section group to get the name of the bootstrapper application assembly to host.
34 var section = ConfigurationManager.GetSection("wix.bootstrapper/host") as HostSection;
35 if (null == section)
36 {
37 throw new MissingAttributeException(); // TODO: throw a more specific exception than this.
38 }
39
40 // Load the BA's IBootstrapperApplicationFactory.
41 var baFactoryType = BootstrapperApplicationFactory.GetBAFactoryTypeFromAssembly(section.AssemblyName);
42 var baFactory = (IBootstrapperApplicationFactory)Activator.CreateInstance(baFactoryType);
43 if (null == baFactory)
44 {
45 throw new InvalidBootstrapperApplicationFactoryException();
46 }
47
48 var ba = baFactory.Create(pEngine, ref command);
49 return ba;
50 }
51
52 /// <summary>
53 /// Locates the <see cref="BootstrapperApplicationFactoryAttribute"/> and returns the specified type.
54 /// </summary>
55 /// <param name="assemblyName">The assembly that defines the IBootstrapperApplicationFactory implementation.</param>
56 /// <returns>The bootstrapper application factory <see cref="Type"/>.</returns>
57 private static Type GetBAFactoryTypeFromAssembly(string assemblyName)
58 {
59 Type baFactoryType = null;
60
61 // Load the requested assembly.
62 Assembly asm = AppDomain.CurrentDomain.Load(assemblyName);
63
64 // If an assembly was loaded and is not the current assembly, check for the required attribute.
65 // This is done to avoid using the BootstrapperApplicationFactoryAttribute which we use at build time
66 // to specify the BootstrapperApplicationFactory assembly in the manifest.
67 if (!Assembly.GetExecutingAssembly().Equals(asm))
68 {
69 // There must be one and only one BootstrapperApplicationFactoryAttribute.
70 // The attribute prevents multiple declarations already.
71 var attrs = (BootstrapperApplicationFactoryAttribute[])asm.GetCustomAttributes(typeof(BootstrapperApplicationFactoryAttribute), false);
72 if (null != attrs)
73 {
74 baFactoryType = attrs[0].BootstrapperApplicationFactoryType;
75 }
76 }
77
78 if (null == baFactoryType)
79 {
80 throw new MissingAttributeException();
81 }
82
83 return baFactoryType;
84 }
85 }
86}
diff --git a/src/WixToolset.Mba.Core/BootstrapperApplicationFactoryAttribute.cs b/src/WixToolset.Mba.Core/BootstrapperApplicationFactoryAttribute.cs
new file mode 100644
index 00000000..781d4ea1
--- /dev/null
+++ b/src/WixToolset.Mba.Core/BootstrapperApplicationFactoryAttribute.cs
@@ -0,0 +1,35 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6
7 /// <summary>
8 /// Identifies the bootstrapper application factory class.
9 /// </summary>
10 /// <remarks>
11 /// This required assembly attribute identifies the bootstrapper application factory class.
12 /// </remarks>
13 [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
14 public sealed class BootstrapperApplicationFactoryAttribute : Attribute
15 {
16 private Type bootstrapperApplicationFactoryType;
17
18 /// <summary>
19 /// Creates a new instance of the <see cref="BootstrapperApplicationFactoryAttribute"/> class.
20 /// </summary>
21 /// <param name="bootstrapperApplicationFactoryType">The <see cref="Type"/> of the BA factory.</param>
22 public BootstrapperApplicationFactoryAttribute(Type bootstrapperApplicationFactoryType)
23 {
24 this.bootstrapperApplicationFactoryType = bootstrapperApplicationFactoryType;
25 }
26
27 /// <summary>
28 /// Gets the type of the bootstrapper application factory class to create.
29 /// </summary>
30 public Type BootstrapperApplicationFactoryType
31 {
32 get { return this.bootstrapperApplicationFactoryType; }
33 }
34 }
35}
diff --git a/src/WixToolset.Mba.Core/BootstrapperCommand.cs b/src/WixToolset.Mba.Core/BootstrapperCommand.cs
new file mode 100644
index 00000000..bbd10e1d
--- /dev/null
+++ b/src/WixToolset.Mba.Core/BootstrapperCommand.cs
@@ -0,0 +1,107 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.ComponentModel;
7 using System.Runtime.InteropServices;
8
9 public sealed class BootstrapperCommand : IBootstrapperCommand
10 {
11 private readonly string commandLine;
12
13 public BootstrapperCommand(
14 LaunchAction action,
15 Display display,
16 Restart restart,
17 string commandLine,
18 int cmdShow,
19 ResumeType resume,
20 IntPtr splashScreen,
21 RelationType relation,
22 bool passthrough,
23 string layoutDirectory)
24 {
25 this.Action = action;
26 this.Display = display;
27 this.Restart = restart;
28 this.commandLine = commandLine;
29 this.CmdShow = cmdShow;
30 this.Resume = resume;
31 this.SplashScreen = splashScreen;
32 this.Relation = relation;
33 this.Passthrough = passthrough;
34 this.LayoutDirectory = layoutDirectory;
35 }
36
37 public LaunchAction Action { get; }
38
39 public Display Display { get; }
40
41 public Restart Restart { get; }
42
43 public string[] CommandLineArgs => GetCommandLineArgs(this.commandLine);
44
45 public int CmdShow { get; }
46
47 public ResumeType Resume { get; }
48
49 public IntPtr SplashScreen { get; }
50
51 public RelationType Relation { get; }
52
53 public bool Passthrough { get; }
54
55 public string LayoutDirectory { get; }
56
57 /// <summary>
58 /// Gets the command line arguments as a string array.
59 /// </summary>
60 /// <returns>
61 /// Array of command line arguments.
62 /// </returns>
63 /// <exception type="Win32Exception">The command line could not be parsed into an array.</exception>
64 /// <remarks>
65 /// This method uses the same parsing as the operating system which handles quotes and spaces correctly.
66 /// </remarks>
67 public static string[] GetCommandLineArgs(string commandLine)
68 {
69 if (null == commandLine)
70 {
71 return new string[0];
72 }
73
74 // Parse the filtered command line arguments into a native array.
75 int argc = 0;
76
77 // CommandLineToArgvW tries to treat the first argument as the path to the process,
78 // which fails pretty miserably if your first argument is something like
79 // FOO="C:\Program Files\My Company". So give it something harmless to play with.
80 IntPtr argv = NativeMethods.CommandLineToArgvW("ignored " + commandLine, out argc);
81
82 if (IntPtr.Zero == argv)
83 {
84 // Throw an exception with the last error.
85 throw new Win32Exception();
86 }
87
88 // Marshal each native array pointer to a managed string.
89 try
90 {
91 // Skip "ignored" argument/hack.
92 string[] args = new string[argc - 1];
93 for (int i = 1; i < argc; ++i)
94 {
95 IntPtr argvi = Marshal.ReadIntPtr(argv, i * IntPtr.Size);
96 args[i - 1] = Marshal.PtrToStringUni(argvi);
97 }
98
99 return args;
100 }
101 finally
102 {
103 NativeMethods.LocalFree(argv);
104 }
105 }
106 }
107}
diff --git a/src/WixToolset.Mba.Core/BootstrapperSectionGroup.cs b/src/WixToolset.Mba.Core/BootstrapperSectionGroup.cs
new file mode 100644
index 00000000..7721c027
--- /dev/null
+++ b/src/WixToolset.Mba.Core/BootstrapperSectionGroup.cs
@@ -0,0 +1,29 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.Configuration;
7
8 /// <summary>
9 /// Handler for the wix.bootstrapper configuration section group.
10 /// </summary>
11 public class BootstrapperSectionGroup : ConfigurationSectionGroup
12 {
13 /// <summary>
14 /// Creates a new instance of the <see cref="BootstrapperSectionGroup"/> class.
15 /// </summary>
16 public BootstrapperSectionGroup()
17 {
18 }
19
20 /// <summary>
21 /// Gets the <see cref="HostSection"/> handler for the mba configuration section.
22 /// </summary>
23 [ConfigurationProperty("host")]
24 public HostSection Host
25 {
26 get { return (HostSection)base.Sections["host"]; }
27 }
28 }
29}
diff --git a/src/WixToolset.Mba.Core/BundleInfo.cs b/src/WixToolset.Mba.Core/BundleInfo.cs
new file mode 100644
index 00000000..51c2d268
--- /dev/null
+++ b/src/WixToolset.Mba.Core/BundleInfo.cs
@@ -0,0 +1,67 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Xml;
9 using System.Xml.XPath;
10
11 public class BundleInfo : IBundleInfo
12 {
13 public bool PerMachine { get; internal set; }
14 public string Name { get; internal set; }
15 public string LogVariable { get; internal set; }
16 public IDictionary<string, IPackageInfo> Packages { get; internal set; }
17
18 internal BundleInfo()
19 {
20 this.Packages = new Dictionary<string, IPackageInfo>();
21 }
22
23 public void AddRelatedBundleAsPackage(DetectRelatedBundleEventArgs e)
24 {
25 var package = PackageInfo.GetRelatedBundleAsPackage(e.ProductCode, e.RelationType, e.PerMachine, e.Version);
26 this.Packages.Add(package.Id, package);
27 }
28
29 public static IBundleInfo ParseBundleFromStream(Stream stream)
30 {
31 XPathDocument manifest = new XPathDocument(stream);
32 XPathNavigator root = manifest.CreateNavigator();
33 return ParseBundleFromXml(root);
34 }
35
36 public static IBundleInfo ParseBundleFromXml(XPathNavigator root)
37 {
38 BundleInfo bundle = new BundleInfo();
39
40 XmlNamespaceManager namespaceManager = new XmlNamespaceManager(root.NameTable);
41 namespaceManager.AddNamespace("p", BootstrapperApplicationData.XMLNamespace);
42 XPathNavigator bundleNode = root.SelectSingleNode("/p:BootstrapperApplicationData/p:WixBundleProperties", namespaceManager);
43
44 if (bundleNode == null)
45 {
46 throw new Exception("Failed to select bundle information.");
47 }
48
49 bool? perMachine = BootstrapperApplicationData.GetYesNoAttribute(bundleNode, "PerMachine");
50 if (perMachine.HasValue)
51 {
52 bundle.PerMachine = perMachine.Value;
53 }
54
55 bundle.Name = BootstrapperApplicationData.GetAttribute(bundleNode, "DisplayName");
56
57 bundle.LogVariable = BootstrapperApplicationData.GetAttribute(bundleNode, "LogPathVariable");
58
59 foreach (var package in PackageInfo.ParsePackagesFromXml(root))
60 {
61 bundle.Packages.Add(package.Id, package);
62 }
63
64 return bundle;
65 }
66 }
67}
diff --git a/src/WixToolset.Mba.Core/Engine.cs b/src/WixToolset.Mba.Core/Engine.cs
new file mode 100644
index 00000000..ad62134f
--- /dev/null
+++ b/src/WixToolset.Mba.Core/Engine.cs
@@ -0,0 +1,516 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.ComponentModel;
7 using System.Runtime.InteropServices;
8 using System.Security;
9 using System.Text;
10
11 /// <summary>
12 /// Container class for the <see cref="IBootstrapperEngine"/> interface.
13 /// </summary>
14 public sealed class Engine : IEngine
15 {
16 // Burn errs on empty strings, so declare initial buffer size.
17 private const int InitialBufferSize = 80;
18 private static readonly string normalizeVersionFormatString = "{0} must be less than or equal to " + UInt16.MaxValue;
19
20 private IBootstrapperEngine engine;
21 private Variables<long> numericVariables;
22 private Variables<SecureString> secureStringVariables;
23 private Variables<string> stringVariables;
24 private Variables<Version> versionVariables;
25
26 /// <summary>
27 /// Creates a new instance of the <see cref="Engine"/> container class.
28 /// </summary>
29 /// <param name="engine">The <see cref="IBootstrapperEngine"/> to contain.</param>
30 internal Engine(IBootstrapperEngine engine)
31 {
32 this.engine = engine;
33
34 // Wrap the calls to get and set numeric variables.
35 this.numericVariables = new Variables<long>(
36 delegate(string name)
37 {
38 long value;
39 int ret = this.engine.GetVariableNumeric(name, out value);
40 if (NativeMethods.S_OK != ret)
41 {
42 throw new Win32Exception(ret);
43 }
44
45 return value;
46 },
47 delegate(string name, long value)
48 {
49 this.engine.SetVariableNumeric(name, value);
50 },
51 delegate(string name)
52 {
53 long value;
54 int ret = this.engine.GetVariableNumeric(name, out value);
55
56 return NativeMethods.E_NOTFOUND != ret;
57 }
58 );
59
60 // Wrap the calls to get and set string variables using SecureStrings.
61 this.secureStringVariables = new Variables<SecureString>(
62 delegate(string name)
63 {
64 var pUniString = this.getStringVariable(name, out var length);
65 try
66 {
67 return this.convertToSecureString(pUniString, length);
68 }
69 finally
70 {
71 if (IntPtr.Zero != pUniString)
72 {
73 Marshal.FreeCoTaskMem(pUniString);
74 }
75 }
76 },
77 delegate(string name, SecureString value)
78 {
79 IntPtr pValue = Marshal.SecureStringToCoTaskMemUnicode(value);
80 try
81 {
82 this.engine.SetVariableString(name, pValue);
83 }
84 finally
85 {
86 Marshal.FreeCoTaskMem(pValue);
87 }
88 },
89 delegate(string name)
90 {
91 return this.containsVariable(name);
92 }
93 );
94
95 // Wrap the calls to get and set string variables.
96 this.stringVariables = new Variables<string>(
97 delegate(string name)
98 {
99 int length;
100 IntPtr pUniString = this.getStringVariable(name, out length);
101 try
102 {
103 return Marshal.PtrToStringUni(pUniString, length);
104 }
105 finally
106 {
107 if (IntPtr.Zero != pUniString)
108 {
109 Marshal.FreeCoTaskMem(pUniString);
110 }
111 }
112 },
113 delegate(string name, string value)
114 {
115 IntPtr pValue = Marshal.StringToCoTaskMemUni(value);
116 try
117 {
118 this.engine.SetVariableString(name, pValue);
119 }
120 finally
121 {
122 Marshal.FreeCoTaskMem(pValue);
123 }
124 },
125 delegate(string name)
126 {
127 return this.containsVariable(name);
128 }
129 );
130
131 // Wrap the calls to get and set version variables.
132 this.versionVariables = new Variables<Version>(
133 delegate(string name)
134 {
135 long value;
136 int ret = this.engine.GetVariableVersion(name, out value);
137 if (NativeMethods.S_OK != ret)
138 {
139 throw new Win32Exception(ret);
140 }
141
142 return LongToVersion(value);
143 },
144 delegate(string name, Version value)
145 {
146 long version = VersionToLong(value);
147 this.engine.SetVariableVersion(name, version);
148 },
149 delegate(string name)
150 {
151 long value;
152 int ret = this.engine.GetVariableVersion(name, out value);
153
154 return NativeMethods.E_NOTFOUND != ret;
155 }
156 );
157 }
158
159 public IVariables<long> NumericVariables
160 {
161 get { return this.numericVariables; }
162 }
163
164 public int PackageCount
165 {
166 get
167 {
168 int count;
169 this.engine.GetPackageCount(out count);
170
171 return count;
172 }
173 }
174
175 public IVariables<SecureString> SecureStringVariables
176 {
177 get { return this.secureStringVariables; }
178 }
179
180 public IVariables<string> StringVariables
181 {
182 get { return this.stringVariables; }
183 }
184
185 public IVariables<Version> VersionVariables
186 {
187 get { return this.versionVariables; }
188 }
189
190 public void Apply(IntPtr hwndParent)
191 {
192 this.engine.Apply(hwndParent);
193 }
194
195 public void CloseSplashScreen()
196 {
197 this.engine.CloseSplashScreen();
198 }
199
200 public void Detect()
201 {
202 this.Detect(IntPtr.Zero);
203 }
204
205 public void Detect(IntPtr hwndParent)
206 {
207 this.engine.Detect(hwndParent);
208 }
209
210 public bool Elevate(IntPtr hwndParent)
211 {
212 int ret = this.engine.Elevate(hwndParent);
213
214 if (NativeMethods.S_OK == ret || NativeMethods.E_ALREADYINITIALIZED == ret)
215 {
216 return true;
217 }
218 else if (NativeMethods.E_CANCELLED == ret)
219 {
220 return false;
221 }
222 else
223 {
224 throw new Win32Exception(ret);
225 }
226 }
227
228 public string EscapeString(string input)
229 {
230 int capacity = InitialBufferSize;
231 StringBuilder sb = new StringBuilder(capacity);
232
233 // Get the size of the buffer.
234 int ret = this.engine.EscapeString(input, sb, ref capacity);
235 if (NativeMethods.E_INSUFFICIENT_BUFFER == ret || NativeMethods.E_MOREDATA == ret)
236 {
237 sb.Capacity = ++capacity; // Add one for the null terminator.
238 ret = this.engine.EscapeString(input, sb, ref capacity);
239 }
240
241 if (NativeMethods.S_OK != ret)
242 {
243 throw new Win32Exception(ret);
244 }
245
246 return sb.ToString();
247 }
248
249 public bool EvaluateCondition(string condition)
250 {
251 bool value;
252 this.engine.EvaluateCondition(condition, out value);
253
254 return value;
255 }
256
257 public string FormatString(string format)
258 {
259 int capacity = InitialBufferSize;
260 StringBuilder sb = new StringBuilder(capacity);
261
262 // Get the size of the buffer.
263 int ret = this.engine.FormatString(format, sb, ref capacity);
264 if (NativeMethods.E_INSUFFICIENT_BUFFER == ret || NativeMethods.E_MOREDATA == ret)
265 {
266 sb.Capacity = ++capacity; // Add one for the null terminator.
267 ret = this.engine.FormatString(format, sb, ref capacity);
268 }
269
270 if (NativeMethods.S_OK != ret)
271 {
272 throw new Win32Exception(ret);
273 }
274
275 return sb.ToString();
276 }
277
278 public void LaunchApprovedExe(IntPtr hwndParent, string approvedExeForElevationId, string arguments)
279 {
280 this.LaunchApprovedExe(hwndParent, approvedExeForElevationId, arguments, 0);
281 }
282
283 public void LaunchApprovedExe(IntPtr hwndParent, string approvedExeForElevationId, string arguments, int waitForInputIdleTimeout)
284 {
285 this.engine.LaunchApprovedExe(hwndParent, approvedExeForElevationId, arguments, waitForInputIdleTimeout);
286 }
287
288 public void Log(LogLevel level, string message)
289 {
290 this.engine.Log(level, message);
291 }
292
293 public void Plan(LaunchAction action)
294 {
295 this.engine.Plan(action);
296 }
297
298 public void SetUpdate(string localSource, string downloadSource, long size, UpdateHashType hashType, byte[] hash)
299 {
300 this.engine.SetUpdate(localSource, downloadSource, size, hashType, hash, null == hash ? 0 : hash.Length);
301 }
302
303 public void SetLocalSource(string packageOrContainerId, string payloadId, string path)
304 {
305 this.engine.SetLocalSource(packageOrContainerId, payloadId, path);
306 }
307
308 public void SetDownloadSource(string packageOrContainerId, string payloadId, string url, string user, string password)
309 {
310 this.engine.SetDownloadSource(packageOrContainerId, payloadId, url, user, password);
311 }
312
313 public int SendEmbeddedError(int errorCode, string message, int uiHint)
314 {
315 int result = 0;
316 this.engine.SendEmbeddedError(errorCode, message, uiHint, out result);
317 return result;
318 }
319
320 public int SendEmbeddedProgress(int progressPercentage, int overallPercentage)
321 {
322 int result = 0;
323 this.engine.SendEmbeddedProgress(progressPercentage, overallPercentage, out result);
324 return result;
325 }
326
327 public void Quit(int exitCode)
328 {
329 this.engine.Quit(exitCode);
330 }
331
332 internal sealed class Variables<T> : IVariables<T>
333 {
334 // .NET 2.0 does not support Func<T, TResult> or Action<T1, T2>.
335 internal delegate T Getter<T>(string name);
336 internal delegate void Setter<T>(string name, T value);
337
338 private Getter<T> getter;
339 private Setter<T> setter;
340 private Predicate<string> contains;
341
342 internal Variables(Getter<T> getter, Setter<T> setter, Predicate<string> contains)
343 {
344 this.getter = getter;
345 this.setter = setter;
346 this.contains = contains;
347 }
348
349 public T this[string name]
350 {
351 get { return this.getter(name); }
352 set { this.setter(name, value); }
353 }
354
355 public bool Contains(string name)
356 {
357 return this.contains(name);
358 }
359 }
360
361 /// <summary>
362 /// Gets whether the variable given by <paramref name="name"/> exists.
363 /// </summary>
364 /// <param name="name">The name of the variable to check.</param>
365 /// <returns>True if the variable given by <paramref name="name"/> exists; otherwise, false.</returns>
366 internal bool containsVariable(string name)
367 {
368 int capacity = 0;
369 IntPtr pValue = IntPtr.Zero;
370 int ret = this.engine.GetVariableString(name, pValue, ref capacity);
371
372 return NativeMethods.E_NOTFOUND != ret;
373 }
374
375 /// <summary>
376 /// Gets the variable given by <paramref name="name"/> as a string.
377 /// </summary>
378 /// <param name="name">The name of the variable to get.</param>
379 /// <param name="length">The length of the Unicode string.</param>
380 /// <returns>The value by a pointer to a Unicode string. Must be freed by Marshal.FreeCoTaskMem.</returns>
381 /// <exception cref="Exception">An error occurred getting the variable.</exception>
382 internal IntPtr getStringVariable(string name, out int length)
383 {
384 int capacity = InitialBufferSize;
385 bool success = false;
386 IntPtr pValue = Marshal.AllocCoTaskMem(capacity * UnicodeEncoding.CharSize);
387 try
388 {
389 // Get the size of the buffer.
390 int ret = this.engine.GetVariableString(name, pValue, ref capacity);
391 if (NativeMethods.E_INSUFFICIENT_BUFFER == ret || NativeMethods.E_MOREDATA == ret)
392 {
393 // Don't need to add 1 for the null terminator, the engine already includes that.
394 pValue = Marshal.ReAllocCoTaskMem(pValue, capacity * UnicodeEncoding.CharSize);
395 ret = this.engine.GetVariableString(name, pValue, ref capacity);
396 }
397
398 if (NativeMethods.S_OK != ret)
399 {
400 throw Marshal.GetExceptionForHR(ret);
401 }
402
403 // The engine only returns the exact length of the string if the buffer was too small, so calculate it ourselves.
404 for (length = 0; length < capacity; ++length)
405 {
406 if(0 == Marshal.ReadInt16(pValue, length * UnicodeEncoding.CharSize))
407 {
408 break;
409 }
410 }
411
412 success = true;
413 return pValue;
414 }
415 finally
416 {
417 if (!success && IntPtr.Zero != pValue)
418 {
419 Marshal.FreeCoTaskMem(pValue);
420 }
421 }
422 }
423
424 /// <summary>
425 /// Initialize a SecureString with the given Unicode string.
426 /// </summary>
427 /// <param name="pUniString">Pointer to Unicode string.</param>
428 /// <param name="length">The string's length.</param>
429 internal SecureString convertToSecureString(IntPtr pUniString, int length)
430 {
431 if (IntPtr.Zero == pUniString)
432 {
433 return null;
434 }
435
436 SecureString value = new SecureString();
437 short s;
438 char c;
439 for (int charIndex = 0; charIndex < length; charIndex++)
440 {
441 s = Marshal.ReadInt16(pUniString, charIndex * UnicodeEncoding.CharSize);
442 c = (char)s;
443 value.AppendChar(c);
444 s = 0;
445 c = (char)0;
446 }
447 return value;
448 }
449
450 public static long VersionToLong(Version version)
451 {
452 // In Windows, each version component has a max value of 65535,
453 // so we truncate the version before shifting it, which will overflow if invalid.
454 long major = (long)(ushort)version.Major << 48;
455 long minor = (long)(ushort)version.Minor << 32;
456 long build = (long)(ushort)version.Build << 16;
457 long revision = (long)(ushort)version.Revision;
458
459 return major | minor | build | revision;
460 }
461
462 public static Version LongToVersion(long version)
463 {
464 int major = (int)((version & ((long)0xffff << 48)) >> 48);
465 int minor = (int)((version & ((long)0xffff << 32)) >> 32);
466 int build = (int)((version & ((long)0xffff << 16)) >> 16);
467 int revision = (int)(version & 0xffff);
468
469 return new Version(major, minor, build, revision);
470 }
471
472 /// <summary>
473 /// Verifies that VersionVariables can pass on the given Version to the engine.
474 /// If the Build or Revision fields are undefined, they are set to zero.
475 /// </summary>
476 public static Version NormalizeVersion(Version version)
477 {
478 if (version == null)
479 {
480 throw new ArgumentNullException("version");
481 }
482
483 int major = version.Major;
484 int minor = version.Minor;
485 int build = version.Build;
486 int revision = version.Revision;
487
488 if (major > UInt16.MaxValue)
489 {
490 throw new ArgumentOutOfRangeException("version", String.Format(normalizeVersionFormatString, "Major"));
491 }
492 if (minor > UInt16.MaxValue)
493 {
494 throw new ArgumentOutOfRangeException("version", String.Format(normalizeVersionFormatString, "Minor"));
495 }
496 if (build > UInt16.MaxValue)
497 {
498 throw new ArgumentOutOfRangeException("version", String.Format(normalizeVersionFormatString, "Build"));
499 }
500 if (build == -1)
501 {
502 build = 0;
503 }
504 if (revision > UInt16.MaxValue)
505 {
506 throw new ArgumentOutOfRangeException("version", String.Format(normalizeVersionFormatString, "Revision"));
507 }
508 if (revision == -1)
509 {
510 revision = 0;
511 }
512
513 return new Version(major, minor, build, revision);
514 }
515 }
516}
diff --git a/src/WixToolset.Mba.Core/EventArgs.cs b/src/WixToolset.Mba.Core/EventArgs.cs
new file mode 100644
index 00000000..9e8e6ecc
--- /dev/null
+++ b/src/WixToolset.Mba.Core/EventArgs.cs
@@ -0,0 +1,1903 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Collections.ObjectModel;
8
9 /// <summary>
10 /// Base class for BA <see cref="EventArgs"/> classes.
11 /// </summary>
12 [Serializable]
13 public abstract class HResultEventArgs : EventArgs
14 {
15 /// <summary>
16 /// Creates a new instance of the <see cref="HResultEventArgs"/> class.
17 /// </summary>
18 public HResultEventArgs()
19 {
20 }
21
22 /// <summary>
23 /// Gets or sets the <see cref="HResult"/> of the operation. This is passed back to the engine.
24 /// </summary>
25 public int HResult { get; set; }
26 }
27
28 /// <summary>
29 /// Base class for cancellable BA <see cref="EventArgs"/> classes.
30 /// </summary>
31 [Serializable]
32 public abstract class CancellableHResultEventArgs : HResultEventArgs
33 {
34 /// <summary>
35 /// Creates a new instance of the <see cref="CancellableHResultEventArgs"/> class.
36 /// </summary>
37 public CancellableHResultEventArgs(bool cancelRecommendation)
38 {
39 this.Cancel = cancelRecommendation;
40 }
41
42 /// <summary>
43 /// Gets or sets whether to cancel the operation. This is passed back to the engine.
44 /// </summary>
45 public bool Cancel { get; set; }
46 }
47
48 /// <summary>
49 /// Base class for <see cref="EventArgs"/> classes that must return a <see cref="Result"/>.
50 /// </summary>
51 [Serializable]
52 public abstract class ResultEventArgs : HResultEventArgs
53 {
54 /// <summary>
55 /// Creates a new instance of the <see cref="ResultEventArgs"/> class.
56 /// </summary>
57 /// <param name="recommendation">Recommended result from engine.</param>
58 /// <param name="result">The result to return to the engine.</param>
59 public ResultEventArgs(Result recommendation, Result result)
60 {
61 this.Recommendation = recommendation;
62 this.Result = result;
63 }
64
65 /// <summary>
66 /// Gets the recommended <see cref="Result"/> of the operation.
67 /// </summary>
68 public Result Recommendation { get; private set; }
69
70 /// <summary>
71 /// Gets or sets the <see cref="Result"/> of the operation. This is passed back to the engine.
72 /// </summary>
73 public Result Result { get; set; }
74 }
75
76 /// <summary>
77 /// Base class for <see cref="EventArgs"/> classes that receive status from the engine.
78 /// </summary>
79 [Serializable]
80 public abstract class StatusEventArgs : HResultEventArgs
81 {
82 /// <summary>
83 /// Creates a new instance of the <see cref="StatusEventArgs"/> class.
84 /// </summary>
85 /// <param name="hrStatus">The return code of the operation.</param>
86 public StatusEventArgs(int hrStatus)
87 {
88 this.Status = hrStatus;
89 }
90
91 /// <summary>
92 /// Gets the return code of the operation.
93 /// </summary>
94 public int Status { get; private set; }
95 }
96
97 /// <summary>
98 /// Base class for <see cref="EventArgs"/> classes that receive status from the engine and return an action.
99 /// </summary>
100 public abstract class ActionEventArgs<T> : StatusEventArgs
101 {
102 /// <summary>
103 /// </summary>
104 /// <param name="hrStatus">The return code of the operation.</param>
105 /// <param name="recommendation">Recommended action from engine.</param>
106 /// <param name="action">The action to perform.</param>
107 public ActionEventArgs(int hrStatus, T recommendation, T action)
108 : base(hrStatus)
109 {
110 this.Recommendation = recommendation;
111 this.Action = action;
112 }
113
114 /// <summary>
115 /// Gets the recommended action from the engine.
116 /// </summary>
117 public T Recommendation { get; private set; }
118
119 /// <summary>
120 /// Gets or sets the action to be performed. This is passed back to the engine.
121 /// </summary>
122 public T Action { get; set; }
123 }
124
125 /// <summary>
126 /// Additional arguments used when startup has begun.
127 /// </summary>
128 [Serializable]
129 public class StartupEventArgs : HResultEventArgs
130 {
131 /// <summary>
132 /// Creates a new instance of the <see cref="StartupEventArgs"/> class.
133 /// </summary>
134 public StartupEventArgs()
135 {
136 }
137 }
138
139 /// <summary>
140 /// Additional arguments used when shutdown has begun.
141 /// </summary>
142 [Serializable]
143 public class ShutdownEventArgs : HResultEventArgs
144 {
145 /// <summary>
146 /// Creates a new instance of the <see cref="ShutdownEventArgs"/> class.
147 /// </summary>
148 public ShutdownEventArgs(BOOTSTRAPPER_SHUTDOWN_ACTION action)
149 {
150 this.Action = action;
151 }
152
153 /// <summary>
154 /// The action for OnShutdown.
155 /// </summary>
156 public BOOTSTRAPPER_SHUTDOWN_ACTION Action { get; set; }
157 }
158
159 /// <summary>
160 /// Additional arguments used when the system is shutting down or the user is logging off.
161 /// </summary>
162 /// <remarks>
163 /// <para>To prevent shutting down or logging off, set <see cref="CancellableHResultEventArgs.Cancel"/> to
164 /// true; otherwise, set it to false.</para>
165 /// <para>By default setup will prevent shutting down or logging off between
166 /// <see cref="BootstrapperApplication.ApplyBegin"/> and <see cref="BootstrapperApplication.ApplyComplete"/>.</para>
167 /// <para>If <see cref="SystemShutdownEventArgs.Reasons"/> contains <see cref="EndSessionReasons.Critical"/>
168 /// the bootstrapper cannot prevent the shutdown and only has a few seconds to save state or perform any other
169 /// critical operations before being closed by the operating system.</para>
170 /// </remarks>
171 [Serializable]
172 public class SystemShutdownEventArgs : CancellableHResultEventArgs
173 {
174 /// <summary>
175 /// Creates a new instance of the <see cref="SystemShutdownEventArgs"/> class.
176 /// </summary>
177 /// <param name="reasons">The reason the application is requested to close or being closed.</param>
178 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
179 public SystemShutdownEventArgs(EndSessionReasons reasons, bool cancelRecommendation)
180 : base(cancelRecommendation)
181 {
182 this.Reasons = reasons;
183 }
184
185 /// <summary>
186 /// Gets the reason the application is requested to close or being closed.
187 /// </summary>
188 /// <remarks>
189 /// <para>To prevent shutting down or logging off, set <see cref="CancellableHResultEventArgs.Cancel"/> to
190 /// true; otherwise, set it to false.</para>
191 /// <para>If <see cref="SystemShutdownEventArgs.Reasons"/> contains <see cref="EndSessionReasons.Critical"/>
192 /// the bootstrapper cannot prevent the shutdown and only has a few seconds to save state or perform any other
193 /// critical operations before being closed by the operating system.</para>
194 /// </remarks>
195 public EndSessionReasons Reasons { get; private set; }
196 }
197
198 /// <summary>
199 /// Additional arguments used when the overall detection phase has begun.
200 /// </summary>
201 [Serializable]
202 public class DetectBeginEventArgs : CancellableHResultEventArgs
203 {
204 /// <summary>
205 /// Creates a new instance of the <see cref="DetectBeginEventArgs"/> class.
206 /// </summary>
207 /// <param name="installed">Specifies whether the bundle is installed.</param>
208 /// <param name="packageCount">The number of packages to detect.</param>
209 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
210 public DetectBeginEventArgs(bool installed, int packageCount, bool cancelRecommendation)
211 : base(cancelRecommendation)
212 {
213 this.Installed = installed;
214 this.PackageCount = packageCount;
215 }
216
217 /// <summary>
218 /// Gets whether the bundle is installed.
219 /// </summary>
220 public bool Installed { get; private set; }
221
222 /// <summary>
223 /// Gets the number of packages to detect.
224 /// </summary>
225 public int PackageCount { get; private set; }
226 }
227
228 /// <summary>
229 /// Additional arguments used when detected a forward compatible bundle.
230 /// </summary>
231 [Serializable]
232 public class DetectForwardCompatibleBundleEventArgs : CancellableHResultEventArgs
233 {
234 /// <summary>
235 /// Creates a new instance of the <see cref="DetectUpdateBeginEventArgs"/> class.
236 /// </summary>
237 /// <param name="bundleId">The identity of the forward compatible bundle.</param>
238 /// <param name="relationType">Relationship type for this forward compatible bundle.</param>
239 /// <param name="bundleTag">The tag of the forward compatible bundle.</param>
240 /// <param name="perMachine">Whether the detected forward compatible bundle is per machine.</param>
241 /// <param name="version">The version of the forward compatible bundle detected.</param>
242 /// <param name="cancelRecommendation">The cancel recommendation from the engine.</param>
243 /// <param name="ignoreBundleRecommendation">The ignore recommendation from the engine.</param>
244 public DetectForwardCompatibleBundleEventArgs(string bundleId, RelationType relationType, string bundleTag, bool perMachine, long version, bool cancelRecommendation, bool ignoreBundleRecommendation)
245 : base(cancelRecommendation)
246 {
247 this.BundleId = bundleId;
248 this.RelationType = relationType;
249 this.BundleTag = bundleTag;
250 this.PerMachine = perMachine;
251 this.Version = Engine.LongToVersion(version);
252 this.IgnoreBundle = ignoreBundleRecommendation;
253 }
254
255 /// <summary>
256 /// Gets the identity of the forward compatible bundle detected.
257 /// </summary>
258 public string BundleId { get; private set; }
259
260 /// <summary>
261 /// Gets the relationship type of the forward compatible bundle.
262 /// </summary>
263 public RelationType RelationType { get; private set; }
264
265 /// <summary>
266 /// Gets the tag of the forward compatible bundle.
267 /// </summary>
268 public string BundleTag { get; private set; }
269
270 /// <summary>
271 /// Gets whether the detected forward compatible bundle is per machine.
272 /// </summary>
273 public bool PerMachine { get; private set; }
274
275 /// <summary>
276 /// Gets the version of the forward compatible bundle detected.
277 /// </summary>
278 public Version Version { get; private set; }
279
280 /// <summary>
281 /// Instructs the engine whether to use the forward compatible bundle.
282 /// </summary>
283 public bool IgnoreBundle { get; set; }
284 }
285
286 /// <summary>
287 /// Additional arguments used when the detection for an update has begun.
288 /// </summary>
289 [Serializable]
290 public class DetectUpdateBeginEventArgs : CancellableHResultEventArgs
291 {
292 /// <summary>
293 /// Creates a new instance of the <see cref="DetectUpdateBeginEventArgs"/> class.
294 /// </summary>
295 /// <param name="updateLocation">The location to check for an updated bundle.</param>
296 /// <param name="cancelRecommendation">The cancel recommendation from the engine.</param>
297 /// <param name="skipRecommendation">The skip recommendation from the engine.</param>
298 public DetectUpdateBeginEventArgs(string updateLocation, bool cancelRecommendation, bool skipRecommendation)
299 : base(cancelRecommendation)
300 {
301 this.UpdateLocation = updateLocation;
302 }
303
304 /// <summary>
305 /// Gets the identity of the bundle to detect.
306 /// </summary>
307 public string UpdateLocation { get; private set; }
308
309 /// <summary>
310 /// Whether to skip checking for bundle updates.
311 /// </summary>
312 public bool Skip { get; set; }
313 }
314
315 /// <summary>
316 /// Additional arguments used when the detection for an update has begun.
317 /// </summary>
318 [Serializable]
319 public class DetectUpdateEventArgs : CancellableHResultEventArgs
320 {
321 /// <summary>
322 /// Creates a new instance of the <see cref="DetectUpdateBeginEventArgs"/> class.
323 /// </summary>
324 /// <param name="updateLocation">The location to check for an updated bundle.</param>
325 /// <param name="size">The expected size of the updated bundle.</param>
326 /// <param name="version">The expected version of the updated bundle.</param>
327 /// <param name="title">The title of the updated bundle.</param>
328 /// <param name="summary">The summary of the updated bundle.</param>
329 /// <param name="contentType">The content type of the content of the updated bundle.</param>
330 /// <param name="content">The content of the updated bundle.</param>
331 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
332 /// <param name="stopRecommendation">The recommendation from the engine.</param>
333 public DetectUpdateEventArgs(string updateLocation, long size, long version, string title, string summary, string contentType, string content, bool cancelRecommendation, bool stopRecommendation)
334 : base(cancelRecommendation)
335 {
336 this.UpdateLocation = updateLocation;
337 this.Size = size;
338 this.Version = Engine.LongToVersion(version);
339 this.Title = title;
340 this.Summary = summary;
341 this.ContentType = contentType;
342 this.Content = content;
343 this.StopProcessingUpdates = stopRecommendation;
344 }
345
346 /// <summary>
347 /// Gets the identity of the bundle to detect.
348 /// </summary>
349 public string UpdateLocation { get; private set; }
350
351 /// <summary>
352 /// Gets the size of the updated bundle.
353 /// </summary>
354 public long Size { get; private set; }
355
356 /// <summary>
357 /// Gets the version of the updated bundle.
358 /// </summary>
359 public Version Version { get; private set; }
360
361 /// <summary>
362 /// Gets the title of the the updated bundle.
363 /// </summary>
364 public string Title { get; private set; }
365
366 /// <summary>
367 /// Gets the summary of the updated bundle.
368 /// </summary>
369 public string Summary { get; private set; }
370
371 /// <summary>
372 /// Gets the content type of the content of the updated bundle.
373 /// </summary>
374 public string ContentType { get; private set; }
375
376 /// <summary>
377 /// Gets the content of the updated bundle.
378 /// </summary>
379 public string Content { get; private set; }
380
381 /// <summary>
382 /// Tells the engine to stop giving the rest of the updates found in the feed.
383 /// </summary>
384 public bool StopProcessingUpdates { get; set; }
385 }
386
387 /// <summary>
388 /// Additional arguments used when the detection for an update has completed.
389 /// </summary>
390 [Serializable]
391 public class DetectUpdateCompleteEventArgs : StatusEventArgs
392 {
393 /// <summary>
394 /// Creates a new instance of the <see cref="DetectUpdateCompleteEventArgs"/> class.
395 /// </summary>
396 /// <param name="hrStatus">The return code of the operation.</param>
397 /// <param name="ignoreRecommendation">The recommendation from the engine.</param>
398 public DetectUpdateCompleteEventArgs(int hrStatus, bool ignoreRecommendation)
399 : base(hrStatus)
400 {
401 this.IgnoreError = ignoreRecommendation;
402 }
403
404 /// <summary>
405 /// If Status is an error, then set this to true to ignore it and continue detecting.
406 /// </summary>
407 public bool IgnoreError { get; set; }
408 }
409
410 /// <summary>
411 /// Additional arguments used when a related bundle has been detected for a bundle.
412 /// </summary>
413 [Serializable]
414 public class DetectRelatedBundleEventArgs : CancellableHResultEventArgs
415 {
416 /// <summary>
417 /// Creates a new instance of the <see cref="DetectRelatedBundleEventArgs"/> class.
418 /// </summary>
419 /// <param name="productCode">The identity of the related package bundle.</param>
420 /// <param name="relationType">Relationship type for this related bundle.</param>
421 /// <param name="bundleTag">The tag of the related package bundle.</param>
422 /// <param name="perMachine">Whether the detected bundle is per machine.</param>
423 /// <param name="version">The version of the related bundle detected.</param>
424 /// <param name="operation">The operation that will be taken on the detected bundle.</param>
425 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
426 public DetectRelatedBundleEventArgs(string productCode, RelationType relationType, string bundleTag, bool perMachine, long version, RelatedOperation operation, bool cancelRecommendation)
427 : base(cancelRecommendation)
428 {
429 this.ProductCode = productCode;
430 this.RelationType = relationType;
431 this.BundleTag = bundleTag;
432 this.PerMachine = perMachine;
433 this.Version = Engine.LongToVersion(version);
434 this.Operation = operation;
435 }
436
437 /// <summary>
438 /// Gets the identity of the related bundle detected.
439 /// </summary>
440 public string ProductCode { get; private set; }
441
442 /// <summary>
443 /// Gets the relationship type of the related bundle.
444 /// </summary>
445 public RelationType RelationType { get; private set; }
446
447 /// <summary>
448 /// Gets the tag of the related package bundle.
449 /// </summary>
450 public string BundleTag { get; private set; }
451
452 /// <summary>
453 /// Gets whether the detected bundle is per machine.
454 /// </summary>
455 public bool PerMachine { get; private set; }
456
457 /// <summary>
458 /// Gets the version of the related bundle detected.
459 /// </summary>
460 public Version Version { get; private set; }
461
462 /// <summary>
463 /// Gets the operation that will be taken on the detected bundle.
464 /// </summary>
465 public RelatedOperation Operation { get; private set; }
466 }
467
468 /// <summary>
469 /// Additional arguments used when the detection for a specific package has begun.
470 /// </summary>
471 [Serializable]
472 public class DetectPackageBeginEventArgs : CancellableHResultEventArgs
473 {
474 /// <summary>
475 /// Creates a new instance of the <see cref="DetectPackageBeginEventArgs"/> class.
476 /// </summary>
477 /// <param name="packageId">The identity of the package to detect.</param>
478 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
479 public DetectPackageBeginEventArgs(string packageId, bool cancelRecommendation)
480 : base(cancelRecommendation)
481 {
482 this.PackageId = packageId;
483 }
484
485 /// <summary>
486 /// Gets the identity of the package to detect.
487 /// </summary>
488 public string PackageId { get; private set; }
489 }
490
491 /// <summary>
492 /// Additional arguments used when a package was not found but a newer package using the same provider key was.
493 /// </summary>
494 [Serializable]
495 public class DetectCompatibleMsiPackageEventArgs : CancellableHResultEventArgs
496 {
497 /// <summary>
498 /// Creates a new instance of the <see cref="DetectCompatibleMsiPackageEventArgs"/> class.
499 /// </summary>
500 /// <param name="packageId">The identity of the package that was not detected.</param>
501 /// <param name="compatiblePackageId">The identity of the compatible package that was detected.</param>
502 /// <param name="compatiblePackageVersion">The version of the compatible package that was detected.</param>
503 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
504 public DetectCompatibleMsiPackageEventArgs(string packageId, string compatiblePackageId, long compatiblePackageVersion, bool cancelRecommendation)
505 : base(cancelRecommendation)
506 {
507 this.PackageId = packageId;
508 this.CompatiblePackageId = compatiblePackageId;
509 this.CompatiblePackageVersion = Engine.LongToVersion(compatiblePackageVersion);
510 }
511
512 /// <summary>
513 /// Gets the identity of the package that was not detected.
514 /// </summary>
515 public string PackageId { get; private set; }
516
517 /// <summary>
518 /// Gets the identity of the compatible package that was detected.
519 /// </summary>
520 public string CompatiblePackageId { get; private set; }
521
522 /// <summary>
523 /// Gets the version of the compatible package that was detected.
524 /// </summary>
525 public Version CompatiblePackageVersion { get; private set; }
526 }
527
528 /// <summary>
529 /// Additional arguments used when a related MSI package has been detected for a package.
530 /// </summary>
531 [Serializable]
532 public class DetectRelatedMsiPackageEventArgs : CancellableHResultEventArgs
533 {
534 /// <summary>
535 /// Creates a new instance of the <see cref="DetectRelatedMsiPackageEventArgs"/> class.
536 /// </summary>
537 /// <param name="packageId">The identity of the package detecting.</param>
538 /// <param name="upgradeCode">The upgrade code of the related package detected.</param>
539 /// <param name="productCode">The identity of the related package detected.</param>
540 /// <param name="perMachine">Whether the detected package is per machine.</param>
541 /// <param name="version">The version of the related package detected.</param>
542 /// <param name="operation">The operation that will be taken on the detected package.</param>
543 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
544 public DetectRelatedMsiPackageEventArgs(string packageId, string upgradeCode, string productCode, bool perMachine, long version, RelatedOperation operation, bool cancelRecommendation)
545 : base(cancelRecommendation)
546 {
547 this.PackageId = packageId;
548 this.UpgradeCode = upgradeCode;
549 this.ProductCode = productCode;
550 this.PerMachine = perMachine;
551 this.Version = Engine.LongToVersion(version);
552 this.Operation = operation;
553 }
554
555 /// <summary>
556 /// Gets the identity of the product's package detected.
557 /// </summary>
558 public string PackageId { get; private set; }
559
560 /// <summary>
561 /// Gets the upgrade code of the related package detected.
562 /// </summary>
563 public string UpgradeCode { get; private set; }
564
565 /// <summary>
566 /// Gets the identity of the related package detected.
567 /// </summary>
568 public string ProductCode { get; private set; }
569
570 /// <summary>
571 /// Gets whether the detected package is per machine.
572 /// </summary>
573 public bool PerMachine { get; private set; }
574
575 /// <summary>
576 /// Gets the version of the related package detected.
577 /// </summary>
578 public Version Version { get; private set; }
579
580 /// <summary>
581 /// Gets the operation that will be taken on the detected package.
582 /// </summary>
583 public RelatedOperation Operation { get; private set; }
584 }
585
586 /// <summary>
587 /// Additional arguments used when a target MSI package has been detected.
588 /// </summary>
589 public class DetectTargetMsiPackageEventArgs : CancellableHResultEventArgs
590 {
591 /// <summary>
592 /// Creates a new instance of the <see cref="DetectMsiFeatureEventArgs"/> class.
593 /// </summary>
594 /// <param name="packageId">Detected package identifier.</param>
595 /// <param name="productCode">Detected product code.</param>
596 /// <param name="state">Package state detected.</param>
597 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
598 public DetectTargetMsiPackageEventArgs(string packageId, string productCode, PackageState state, bool cancelRecommendation)
599 : base(cancelRecommendation)
600 {
601 this.PackageId = packageId;
602 this.ProductCode = productCode;
603 this.State = state;
604 }
605
606 /// <summary>
607 /// Gets the identity of the target's package detected.
608 /// </summary>
609 public string PackageId { get; private set; }
610
611 /// <summary>
612 /// Gets the product code of the target MSI detected.
613 /// </summary>
614 public string ProductCode { get; private set; }
615
616 /// <summary>
617 /// Gets the detected patch package state.
618 /// </summary>
619 public PackageState State { get; private set; }
620 }
621
622 /// <summary>
623 /// Additional arguments used when a feature in an MSI package has been detected.
624 /// </summary>
625 public class DetectMsiFeatureEventArgs : CancellableHResultEventArgs
626 {
627 /// <summary>
628 /// Creates a new instance of the <see cref="DetectMsiFeatureEventArgs"/> class.
629 /// </summary>
630 /// <param name="packageId">Detected package identifier.</param>
631 /// <param name="featureId">Detected feature identifier.</param>
632 /// <param name="state">Feature state detected.</param>
633 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
634 public DetectMsiFeatureEventArgs(string packageId, string featureId, FeatureState state, bool cancelRecommendation)
635 : base(cancelRecommendation)
636 {
637 this.PackageId = packageId;
638 this.FeatureId = featureId;
639 this.State = state;
640 }
641
642 /// <summary>
643 /// Gets the identity of the feature's package detected.
644 /// </summary>
645 public string PackageId { get; private set; }
646
647 /// <summary>
648 /// Gets the identity of the feature detected.
649 /// </summary>
650 public string FeatureId { get; private set; }
651
652 /// <summary>
653 /// Gets the detected feature state.
654 /// </summary>
655 public FeatureState State { get; private set; }
656 }
657
658 /// <summary>
659 /// Additional arguments used when the detection for a specific package has completed.
660 /// </summary>
661 [Serializable]
662 public class DetectPackageCompleteEventArgs : StatusEventArgs
663 {
664 /// <summary>
665 /// Creates a new instance of the <see cref="DetectPackageCompleteEventArgs"/> class.
666 /// </summary>
667 /// <param name="packageId">The identity of the package detected.</param>
668 /// <param name="hrStatus">The return code of the operation.</param>
669 /// <param name="state">The state of the specified package.</param>
670 public DetectPackageCompleteEventArgs(string packageId, int hrStatus, PackageState state)
671 : base(hrStatus)
672 {
673 this.PackageId = packageId;
674 this.State = state;
675 }
676
677 /// <summary>
678 /// Gets the identity of the package detected.
679 /// </summary>
680 public string PackageId { get; private set; }
681
682 /// <summary>
683 /// Gets the state of the specified package.
684 /// </summary>
685 public PackageState State { get; private set; }
686 }
687
688 /// <summary>
689 /// Additional arguments used when the detection phase has completed.
690 /// </summary>
691 [Serializable]
692 public class DetectCompleteEventArgs : StatusEventArgs
693 {
694 /// <summary>
695 /// Creates a new instance of the <see cref="DetectCompleteEventArgs"/> class.
696 /// </summary>
697 /// <param name="hrStatus">The return code of the operation.</param>
698 public DetectCompleteEventArgs(int hrStatus)
699 : base(hrStatus)
700 {
701 }
702 }
703
704 /// <summary>
705 /// Additional arguments used when the engine has begun planning the installation.
706 /// </summary>
707 [Serializable]
708 public class PlanBeginEventArgs : CancellableHResultEventArgs
709 {
710 /// <summary>
711 /// Creates a new instance of the <see cref="PlanBeginEventArgs"/> class.
712 /// </summary>
713 /// <param name="packageCount">The number of packages to plan for.</param>
714 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
715 public PlanBeginEventArgs(int packageCount, bool cancelRecommendation)
716 : base(cancelRecommendation)
717 {
718 this.PackageCount = packageCount;
719 }
720
721 /// <summary>
722 /// Gets the number of packages to plan for.
723 /// </summary>
724 public int PackageCount { get; private set; }
725 }
726
727 /// <summary>
728 /// Additional arguments used when the engine has begun planning for a related bundle.
729 /// </summary>
730 [Serializable]
731 public class PlanRelatedBundleEventArgs : CancellableHResultEventArgs
732 {
733 /// <summary>
734 /// Creates a new instance of the <see cref="PlanRelatedBundleEventArgs"/> class.
735 /// </summary>
736 /// <param name="bundleId">The identity of the bundle to plan for.</param>
737 /// <param name="recommendedState">The recommended requested state for the bundle.</param>
738 /// <param name="state">The requested state for the bundle.</param>
739 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
740 public PlanRelatedBundleEventArgs(string bundleId, RequestState recommendedState, RequestState state, bool cancelRecommendation)
741 : base(cancelRecommendation)
742 {
743 this.BundleId = bundleId;
744 this.RecommendedState = recommendedState;
745 this.State = state;
746 }
747
748 /// <summary>
749 /// Gets the identity of the bundle to plan for.
750 /// </summary>
751 public string BundleId { get; private set; }
752
753 /// <summary>
754 /// Gets the recommended requested state for the bundle.
755 /// </summary>
756 public RequestState RecommendedState { get; private set; }
757
758 /// <summary>
759 /// Gets or sets the requested state for the bundle.
760 /// </summary>
761 public RequestState State { get; set; }
762 }
763
764 /// <summary>
765 /// Additional arguments used when the engine has begun planning the installation of a specific package.
766 /// </summary>
767 [Serializable]
768 public class PlanPackageBeginEventArgs : CancellableHResultEventArgs
769 {
770 /// <summary>
771 /// Creates a new instance of the <see cref="PlanPackageBeginEventArgs"/> class.
772 /// </summary>
773 /// <param name="packageId">The identity of the package to plan for.</param>
774 /// <param name="recommendedState">The recommended requested state for the package.</param>
775 /// <param name="state">The requested state for the package.</param>
776 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
777 public PlanPackageBeginEventArgs(string packageId, RequestState recommendedState, RequestState state, bool cancelRecommendation)
778 : base(cancelRecommendation)
779 {
780 this.PackageId = packageId;
781 this.RecommendedState = recommendedState;
782 this.State = state;
783 }
784
785 /// <summary>
786 /// Gets the identity of the package to plan for.
787 /// </summary>
788 public string PackageId { get; private set; }
789
790 /// <summary>
791 /// Gets the recommended requested state for the package.
792 /// </summary>
793 public RequestState RecommendedState { get; private set; }
794
795 /// <summary>
796 /// Gets or sets the requested state for the package.
797 /// </summary>
798 public RequestState State { get; set; }
799 }
800
801 /// <summary>
802 /// Additional arguments used when the engine is about to plan a newer package using the same provider key.
803 /// </summary>
804 [Serializable]
805 public class PlanCompatibleMsiPackageBeginEventArgs : CancellableHResultEventArgs
806 {
807 /// <summary>
808 /// Creates a new instance of the <see cref="PlanCompatibleMsiPackageBeginEventArgs"/> class.
809 /// </summary>
810 /// <param name="packageId">The identity of the package that was not detected.</param>
811 /// <param name="compatiblePackageId">The identity of the compatible package that was detected.</param>
812 /// <param name="compatiblePackageVersion">The version of the compatible package that was detected.</param>
813 /// <param name="recommendedState">The recommended request state for the compatible package.</param>
814 /// <param name="state">The requested state for the compatible package.</param>
815 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
816 public PlanCompatibleMsiPackageBeginEventArgs(string packageId, string compatiblePackageId, long compatiblePackageVersion, RequestState recommendedState, RequestState state, bool cancelRecommendation)
817 : base(cancelRecommendation)
818 {
819 this.PackageId = packageId;
820 this.CompatiblePackageId = compatiblePackageId;
821 this.CompatiblePackageVersion = Engine.LongToVersion(compatiblePackageVersion);
822 this.RecommendedState = recommendedState;
823 this.State = state;
824 }
825
826 /// <summary>
827 /// Gets the identity of the package that was not detected.
828 /// </summary>
829 public string PackageId { get; private set; }
830
831 /// <summary>
832 /// Gets the identity of the compatible package detected.
833 /// </summary>
834 public string CompatiblePackageId { get; private set; }
835
836 /// <summary>
837 /// Gets the version of the compatible package detected.
838 /// </summary>
839 public Version CompatiblePackageVersion { get; private set; }
840
841 /// <summary>
842 /// Gets the recommended state to use for the compatible package for planning.
843 /// </summary>
844 public RequestState RecommendedState { get; private set; }
845
846 /// <summary>
847 /// Gets or sets the state to use for the compatible package for planning.
848 /// </summary>
849 public RequestState State { get; set; }
850 }
851
852 /// <summary>
853 /// Additional arguments used when the engine has completed planning the installation of a specific package.
854 /// </summary>
855 [Serializable]
856 public class PlanCompatibleMsiPackageCompleteEventArgs : StatusEventArgs
857 {
858 /// <summary>
859 /// Creates a new instance of the <see cref="PlanCompatibleMsiPackageCompleteEventArgs"/> class.
860 /// </summary>
861 /// <param name="packageId">The identity of the package planned for.</param>
862 /// <param name="compatiblePackageId">The identity of the compatible package that was detected.</param>
863 /// <param name="hrStatus">The return code of the operation.</param>
864 /// <param name="state">The current state of the package.</param>
865 /// <param name="requested">The requested state for the package</param>
866 /// <param name="execute">The execution action to take.</param>
867 /// <param name="rollback">The rollback action to take.</param>
868 public PlanCompatibleMsiPackageCompleteEventArgs(string packageId, string compatiblePackageId, int hrStatus, PackageState state, RequestState requested, ActionState execute, ActionState rollback)
869 : base(hrStatus)
870 {
871 this.PackageId = packageId;
872 this.CompatiblePackageId = compatiblePackageId;
873 this.State = state;
874 this.Requested = requested;
875 this.Execute = execute;
876 this.Rollback = rollback;
877 }
878
879 /// <summary>
880 /// Gets the identity of the package planned for.
881 /// </summary>
882 public string PackageId { get; private set; }
883
884 /// <summary>
885 /// Gets the identity of the compatible package detected.
886 /// </summary>
887 public string CompatiblePackageId { get; private set; }
888
889 /// <summary>
890 /// Gets the current state of the package.
891 /// </summary>
892 public PackageState State { get; private set; }
893
894 /// <summary>
895 /// Gets the requested state for the package.
896 /// </summary>
897 public RequestState Requested { get; private set; }
898
899 /// <summary>
900 /// Gets the execution action to take.
901 /// </summary>
902 public ActionState Execute { get; private set; }
903
904 /// <summary>
905 /// Gets the rollback action to take.
906 /// </summary>
907 public ActionState Rollback { get; private set; }
908 }
909
910 /// <summary>
911 /// Additional arguments used when engine is about to plan a MSP applied to a target MSI package.
912 /// </summary>
913 [Serializable]
914 public class PlanTargetMsiPackageEventArgs : CancellableHResultEventArgs
915 {
916 /// <summary>
917 /// Creates a new instance of the <see cref="PlanMsiFeatureEventArgs"/> class.
918 /// </summary>
919 /// <param name="packageId">Package identifier of the patch being planned.</param>
920 /// <param name="productCode">Product code identifier being planned.</param>
921 /// <param name="recommendedState">Recommended package state of the patch being planned.</param>
922 /// <param name="state">Package state of the patch being planned.</param>
923 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
924 public PlanTargetMsiPackageEventArgs(string packageId, string productCode, RequestState recommendedState, RequestState state, bool cancelRecommendation)
925 : base(cancelRecommendation)
926 {
927 this.PackageId = packageId;
928 this.ProductCode = productCode;
929 this.RecommendedState = recommendedState;
930 this.State = state;
931 }
932
933 /// <summary>
934 /// Gets the identity of the patch package to plan.
935 /// </summary>
936 public string PackageId { get; private set; }
937
938 /// <summary>
939 /// Gets the identity of the patch's target MSI to plan.
940 /// </summary>
941 public string ProductCode { get; private set; }
942
943 /// <summary>
944 /// Gets the recommended state of the patch to use by planning.
945 /// </summary>
946 public RequestState RecommendedState { get; private set; }
947
948 /// <summary>
949 /// Gets or sets the state of the patch to use by planning.
950 /// </summary>
951 public RequestState State { get; set; }
952 }
953
954 /// <summary>
955 /// Additional arguments used when engine is about to plan a feature in an MSI package.
956 /// </summary>
957 [Serializable]
958 public class PlanMsiFeatureEventArgs : CancellableHResultEventArgs
959 {
960 /// <summary>
961 /// Creates a new instance of the <see cref="PlanMsiFeatureEventArgs"/> class.
962 /// </summary>
963 /// <param name="packageId">Package identifier being planned.</param>
964 /// <param name="featureId">Feature identifier being planned.</param>
965 /// <param name="recommendedState">Recommended feature state being planned.</param>
966 /// <param name="state">Feature state being planned.</param>
967 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
968 public PlanMsiFeatureEventArgs(string packageId, string featureId, FeatureState recommendedState, FeatureState state, bool cancelRecommendation)
969 : base(cancelRecommendation)
970 {
971 this.PackageId = packageId;
972 this.FeatureId = featureId;
973 this.RecommendedState = recommendedState;
974 this.State = state;
975 }
976
977 /// <summary>
978 /// Gets the identity of the feature's package to plan.
979 /// </summary>
980 public string PackageId { get; private set; }
981
982 /// <summary>
983 /// Gets the identity of the feature to plan.
984 /// </summary>
985 public string FeatureId { get; private set; }
986
987 /// <summary>
988 /// Gets the recommended feature state to use by planning.
989 /// </summary>
990 public FeatureState RecommendedState { get; private set; }
991
992 /// <summary>
993 /// Gets or sets the feature state to use by planning.
994 /// </summary>
995 public FeatureState State { get; set; }
996 }
997
998 /// <summary>
999 /// Additional arguments used when then engine has completed planning the installation of a specific package.
1000 /// </summary>
1001 [Serializable]
1002 public class PlanPackageCompleteEventArgs : StatusEventArgs
1003 {
1004 /// <summary>
1005 /// Creates a new instance of the <see cref="PlanPackageCompleteEventArgs"/> class.
1006 /// </summary>
1007 /// <param name="packageId">The identity of the package planned for.</param>
1008 /// <param name="hrStatus">The return code of the operation.</param>
1009 /// <param name="state">The current state of the package.</param>
1010 /// <param name="requested">The requested state for the package</param>
1011 /// <param name="execute">The execution action to take.</param>
1012 /// <param name="rollback">The rollback action to take.</param>
1013 public PlanPackageCompleteEventArgs(string packageId, int hrStatus, PackageState state, RequestState requested, ActionState execute, ActionState rollback)
1014 : base(hrStatus)
1015 {
1016 this.PackageId = packageId;
1017 this.State = state;
1018 this.Requested = requested;
1019 this.Execute = execute;
1020 this.Rollback = rollback;
1021 }
1022
1023 /// <summary>
1024 /// Gets the identity of the package planned for.
1025 /// </summary>
1026 public string PackageId { get; private set; }
1027
1028 /// <summary>
1029 /// Gets the current state of the package.
1030 /// </summary>
1031 public PackageState State { get; private set; }
1032
1033 /// <summary>
1034 /// Gets the requested state for the package.
1035 /// </summary>
1036 public RequestState Requested { get; private set; }
1037
1038 /// <summary>
1039 /// Gets the execution action to take.
1040 /// </summary>
1041 public ActionState Execute { get; private set; }
1042
1043 /// <summary>
1044 /// Gets the rollback action to take.
1045 /// </summary>
1046 public ActionState Rollback { get; private set; }
1047 }
1048
1049 /// <summary>
1050 /// Additional arguments used when the engine has completed planning the installation.
1051 /// </summary>
1052 [Serializable]
1053 public class PlanCompleteEventArgs : StatusEventArgs
1054 {
1055 /// <summary>
1056 /// Creates a new instance of the <see cref="PlanCompleteEventArgs"/> class.
1057 /// </summary>
1058 /// <param name="hrStatus">The return code of the operation.</param>
1059 public PlanCompleteEventArgs(int hrStatus)
1060 : base(hrStatus)
1061 {
1062 }
1063 }
1064
1065 /// <summary>
1066 /// Additional arguments used when the engine has begun installing the bundle.
1067 /// </summary>
1068 [Serializable]
1069 public class ApplyBeginEventArgs : CancellableHResultEventArgs
1070 {
1071 /// <summary>
1072 /// Creates a new instance of the <see cref="ApplyBeginEventArgs"/> class.
1073 /// </summary>
1074 /// <param name="phaseCount">The number of phases during apply.</param>
1075 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
1076 public ApplyBeginEventArgs(int phaseCount, bool cancelRecommendation)
1077 : base(cancelRecommendation)
1078 {
1079 this.PhaseCount = phaseCount;
1080 }
1081
1082 /// <summary>
1083 /// Gets the number of phases that the engine will go through in apply.
1084 /// There are currently two possible phases: cache and execute.
1085 /// </summary>
1086 public int PhaseCount { get; private set; }
1087 }
1088
1089 /// <summary>
1090 /// Additional arguments used when the engine is about to start the elevated process.
1091 /// </summary>
1092 [Serializable]
1093 public class ElevateBeginEventArgs : CancellableHResultEventArgs
1094 {
1095 /// <summary>
1096 /// Creates a new instance of the <see cref="ElevateBeginEventArgs"/> class.
1097 /// </summary>
1098 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
1099 public ElevateBeginEventArgs(bool cancelRecommendation)
1100 : base(cancelRecommendation)
1101 {
1102 }
1103 }
1104
1105 /// <summary>
1106 /// Additional arguments used when the engine has completed starting the elevated process.
1107 /// </summary>
1108 [Serializable]
1109 public class ElevateCompleteEventArgs : StatusEventArgs
1110 {
1111 /// <summary>
1112 /// Creates a new instance of the <see cref="ElevateCompleteEventArgs"/> class.
1113 /// </summary>
1114 /// <param name="hrStatus">The return code of the operation.</param>
1115 public ElevateCompleteEventArgs(int hrStatus)
1116 : base(hrStatus)
1117 {
1118 }
1119 }
1120
1121 /// <summary>
1122 /// Additional arguments used when the engine has changed progress for the bundle installation.
1123 /// </summary>
1124 [Serializable]
1125 public class ProgressEventArgs : CancellableHResultEventArgs
1126 {
1127 /// <summary>
1128 /// Creates an new instance of the <see cref="ProgressEventArgs"/> class.
1129 /// </summary>
1130 /// <param name="progressPercentage">The percentage from 0 to 100 completed for a package.</param>
1131 /// <param name="overallPercentage">The percentage from 0 to 100 completed for the bundle.</param>
1132 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
1133 public ProgressEventArgs(int progressPercentage, int overallPercentage, bool cancelRecommendation)
1134 : base(cancelRecommendation)
1135 {
1136 this.ProgressPercentage = progressPercentage;
1137 this.OverallPercentage = overallPercentage;
1138 }
1139
1140 /// <summary>
1141 /// Gets the percentage from 0 to 100 completed for a package.
1142 /// </summary>
1143 public int ProgressPercentage { get; private set; }
1144
1145 /// <summary>
1146 /// Gets the percentage from 0 to 100 completed for the bundle.
1147 /// </summary>
1148 public int OverallPercentage { get; private set; }
1149 }
1150
1151 /// <summary>
1152 /// Additional arguments used when the engine has encountered an error.
1153 /// </summary>
1154 [Serializable]
1155 public class ErrorEventArgs : ResultEventArgs
1156 {
1157 /// <summary>
1158 /// Creates a new instance of the <see cref="ErrorEventArgs"/> class.
1159 /// </summary>
1160 /// <param name="errorType">The error type.</param>
1161 /// <param name="packageId">The identity of the package that yielded the error.</param>
1162 /// <param name="errorCode">The error code.</param>
1163 /// <param name="errorMessage">The error message.</param>
1164 /// <param name="dwUIHint">Recommended display flags for an error dialog.</param>
1165 /// <param name="data">The exteded data for the error.</param>
1166 /// <param name="recommendation">Recommended result from engine.</param>
1167 /// <param name="result">The result to return to the engine.</param>
1168 public ErrorEventArgs(ErrorType errorType, string packageId, int errorCode, string errorMessage, int dwUIHint, string[] data, Result recommendation, Result result)
1169 : base(recommendation, result)
1170 {
1171 this.ErrorType = errorType;
1172 this.PackageId = packageId;
1173 this.ErrorCode = errorCode;
1174 this.ErrorMessage = errorMessage;
1175 this.UIHint = dwUIHint;
1176 this.Data = new ReadOnlyCollection<string>(data ?? new string[] { });
1177 }
1178
1179 /// <summary>
1180 /// Gets the type of error that occurred.
1181 /// </summary>
1182 public ErrorType ErrorType { get; private set; }
1183
1184 /// <summary>
1185 /// Gets the identity of the package that yielded the error.
1186 /// </summary>
1187 public string PackageId { get; private set; }
1188
1189 /// <summary>
1190 /// Gets the error code.
1191 /// </summary>
1192 public int ErrorCode { get; private set; }
1193
1194 /// <summary>
1195 /// Gets the error message.
1196 /// </summary>
1197 public string ErrorMessage { get; private set; }
1198
1199 /// <summary>
1200 /// Gets the recommended display flags for an error dialog.
1201 /// </summary>
1202 public int UIHint { get; private set; }
1203
1204 /// <summary>
1205 /// Gets the extended data for the error.
1206 /// </summary>
1207 public IList<string> Data { get; private set; }
1208 }
1209
1210 /// <summary>
1211 /// Additional arguments used when the engine has begun registering the location and visibility of the bundle.
1212 /// </summary>
1213 [Serializable]
1214 public class RegisterBeginEventArgs : CancellableHResultEventArgs
1215 {
1216 /// <summary>
1217 /// Creates a new instance of the <see cref="RegisterBeginEventArgs"/> class.
1218 /// </summary>
1219 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
1220 public RegisterBeginEventArgs(bool cancelRecommendation)
1221 : base(cancelRecommendation)
1222 {
1223 }
1224 }
1225
1226 /// <summary>
1227 /// Additional arguments used when the engine has completed registering the location and visilibity of the bundle.
1228 /// </summary>
1229 [Serializable]
1230 public class RegisterCompleteEventArgs : StatusEventArgs
1231 {
1232 /// <summary>
1233 /// Creates a new instance of the <see cref="RegisterCompleteEventArgs"/> class.
1234 /// </summary>
1235 /// <param name="hrStatus">The return code of the operation.</param>
1236 public RegisterCompleteEventArgs(int hrStatus)
1237 : base(hrStatus)
1238 {
1239 }
1240 }
1241
1242 /// <summary>
1243 /// Additional arguments used when the engine has begun removing the registration for the location and visibility of the bundle.
1244 /// </summary>
1245 [Serializable]
1246 public class UnregisterBeginEventArgs : CancellableHResultEventArgs
1247 {
1248 /// <summary>
1249 /// Creates a new instance of the <see cref="UnregisterBeginEventArgs"/> class.
1250 /// </summary>
1251 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
1252 public UnregisterBeginEventArgs(bool cancelRecommendation)
1253 : base(cancelRecommendation)
1254 {
1255 }
1256 }
1257
1258 /// <summary>
1259 /// Additional arguments used when the engine has completed removing the registration for the location and visibility of the bundle.
1260 /// </summary>
1261 [Serializable]
1262 public class UnregisterCompleteEventArgs : StatusEventArgs
1263 {
1264 /// <summary>
1265 /// Creates a new instance of the <see cref="UnregisterCompleteEventArgs"/> class.
1266 /// </summary>
1267 /// <param name="hrStatus">The return code of the operation.</param>
1268 public UnregisterCompleteEventArgs(int hrStatus)
1269 : base(hrStatus)
1270 {
1271 }
1272 }
1273
1274 /// <summary>
1275 /// Additional arguments used when the engine has begun caching the installation sources.
1276 /// </summary>
1277 [Serializable]
1278 public class CacheBeginEventArgs : CancellableHResultEventArgs
1279 {
1280 /// <summary>
1281 /// Creates a new instance of the <see cref="CacheBeginEventArgs"/> class.
1282 /// </summary>
1283 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
1284 public CacheBeginEventArgs(bool cancelRecommendation)
1285 : base(cancelRecommendation)
1286 {
1287 }
1288 }
1289
1290 /// <summary>
1291 /// Additional arguments used when the engine begins to acquire containers or payloads.
1292 /// </summary>
1293 [Serializable]
1294 public class CacheAcquireBeginEventArgs : CancellableHResultEventArgs
1295 {
1296 /// <summary>
1297 /// Creates a new instance of the <see cref="CacheAcquireBeginEventArgs"/> class.
1298 /// </summary>
1299 public CacheAcquireBeginEventArgs(string packageOrContainerId, string payloadId, CacheOperation operation, string source, bool cancelRecommendation)
1300 : base(cancelRecommendation)
1301 {
1302 this.PackageOrContainerId = packageOrContainerId;
1303 this.PayloadId = payloadId;
1304 this.Operation = operation;
1305 this.Source = source;
1306 }
1307
1308 /// <summary>
1309 /// Gets the identifier of the container or package.
1310 /// </summary>
1311 public string PackageOrContainerId { get; private set; }
1312
1313 /// <summary>
1314 /// Gets the identifier of the payload (if acquiring a payload).
1315 /// </summary>
1316 public string PayloadId { get; private set; }
1317
1318 /// <summary>
1319 /// Gets the cache acquire operation.
1320 /// </summary>
1321 public CacheOperation Operation { get; private set; }
1322
1323 /// <summary>
1324 /// Gets the source of the container or payload.
1325 /// </summary>
1326 public string Source { get; private set; }
1327 }
1328
1329 /// <summary>
1330 /// Additional arguments used when the engine acquires some part of a container or payload.
1331 /// </summary>
1332 [Serializable]
1333 public class CacheAcquireProgressEventArgs : CancellableHResultEventArgs
1334 {
1335 /// <summary>
1336 /// Creates a new instance of the <see cref="CacheAcquireBeginEventArgs"/> class.
1337 /// </summary>
1338 public CacheAcquireProgressEventArgs(string packageOrContainerId, string payloadId, long progress, long total, int overallPercentage, bool cancelRecommendation)
1339 : base(cancelRecommendation)
1340 {
1341 this.PackageOrContainerId = packageOrContainerId;
1342 this.PayloadId = payloadId;
1343 this.Progress = progress;
1344 this.Total = total;
1345 this.OverallPercentage = overallPercentage;
1346 }
1347
1348 /// <summary>
1349 /// Gets the identifier of the container or package.
1350 /// </summary>
1351 public string PackageOrContainerId { get; private set; }
1352
1353 /// <summary>
1354 /// Gets the identifier of the payload (if acquiring a payload).
1355 /// </summary>
1356 public string PayloadId { get; private set; }
1357
1358 /// <summary>
1359 /// Gets the number of bytes cached thus far.
1360 /// </summary>
1361 public long Progress { get; private set; }
1362
1363 /// <summary>
1364 /// Gets the total bytes to cache.
1365 /// </summary>
1366 public long Total { get; private set; }
1367
1368 /// <summary>
1369 /// Gets the overall percentage of progress of caching.
1370 /// </summary>
1371 public int OverallPercentage { get; private set; }
1372 }
1373
1374 /// <summary>
1375 /// Additional arguments used when the engine completes the acquisition of a container or payload.
1376 /// </summary>
1377 [Serializable]
1378 public class CacheAcquireCompleteEventArgs : ActionEventArgs<BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION>
1379 {
1380 /// <summary>
1381 /// Creates a new instance of the <see cref="CacheAcquireCompleteEventArgs"/> class.
1382 /// </summary>
1383 public CacheAcquireCompleteEventArgs(string packageOrContainerId, string payloadId, int hrStatus, BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION recommendation, BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION action)
1384 : base(hrStatus, recommendation, action)
1385 {
1386 this.PackageOrContainerId = packageOrContainerId;
1387 this.PayloadId = payloadId;
1388 }
1389
1390 /// <summary>
1391 /// Gets the identifier of the container or package.
1392 /// </summary>
1393 public string PackageOrContainerId { get; private set; }
1394
1395 /// <summary>
1396 /// Gets the identifier of the payload (if acquiring a payload).
1397 /// </summary>
1398 public string PayloadId { get; private set; }
1399 }
1400
1401 /// <summary>
1402 /// Additional arguments used when the engine starts the verification of a payload.
1403 /// </summary>
1404 [Serializable]
1405 public class CacheVerifyBeginEventArgs : CancellableHResultEventArgs
1406 {
1407 /// <summary>
1408 /// Creates a new instance of the <see cref="CacheVerifyBeginEventArgs"/> class.
1409 /// </summary>
1410 public CacheVerifyBeginEventArgs(string packageId, string payloadId, bool cancelRecommendation)
1411 : base(cancelRecommendation)
1412 {
1413 this.PackageId = packageId;
1414 this.PayloadId = payloadId;
1415 }
1416
1417 /// <summary>
1418 /// Gets the identifier of the package.
1419 /// </summary>
1420 public string PackageId { get; private set; }
1421
1422 /// <summary>
1423 /// Gets the identifier of the payload.
1424 /// </summary>
1425 public string PayloadId { get; private set; }
1426 }
1427
1428 /// <summary>
1429 /// Additional arguments used when the engine completes the verification of a payload.
1430 /// </summary>
1431 [Serializable]
1432 public class CacheVerifyCompleteEventArgs : ActionEventArgs<BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION>
1433 {
1434 /// <summary>
1435 /// Creates a new instance of the <see cref="CacheVerifyCompleteEventArgs"/> class.
1436 /// </summary>
1437 public CacheVerifyCompleteEventArgs(string packageId, string payloadId, int hrStatus, BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION recommendation, BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action)
1438 : base(hrStatus, recommendation, action)
1439 {
1440 this.PackageId = packageId;
1441 this.PayloadId = payloadId;
1442 }
1443
1444 /// <summary>
1445 /// Gets the identifier of the package.
1446 /// </summary>
1447 public string PackageId { get; private set; }
1448
1449 /// <summary>
1450 /// Gets the identifier of the payload.
1451 /// </summary>
1452 public string PayloadId { get; private set; }
1453 }
1454
1455 /// <summary>
1456 /// Additional arguments used after the engine has cached the installation sources.
1457 /// </summary>
1458 [Serializable]
1459 public class CacheCompleteEventArgs : StatusEventArgs
1460 {
1461 /// <summary>
1462 /// Creates a new instance of the <see cref="CacheCompleteEventArgs"/> class.
1463 /// </summary>
1464 /// <param name="hrStatus">The return code of the operation.</param>
1465 public CacheCompleteEventArgs(int hrStatus)
1466 : base(hrStatus)
1467 {
1468 }
1469 }
1470
1471 /// <summary>
1472 /// Additional arguments used when the engine has begun installing packages.
1473 /// </summary>
1474 [Serializable]
1475 public class ExecuteBeginEventArgs : CancellableHResultEventArgs
1476 {
1477 /// <summary>
1478 /// Creates a new instance of the <see cref="ExecuteBeginEventArgs"/> class.
1479 /// </summary>
1480 /// <param name="packageCount">The number of packages to act on.</param>
1481 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
1482 public ExecuteBeginEventArgs(int packageCount, bool cancelRecommendation)
1483 : base(cancelRecommendation)
1484 {
1485 this.PackageCount = packageCount;
1486 }
1487
1488 /// <summary>
1489 /// Gets the number of packages to act on.
1490 /// </summary>
1491 public int PackageCount { get; private set; }
1492 }
1493
1494 /// <summary>
1495 /// Additional arguments used when the engine has begun installing a specific package.
1496 /// </summary>
1497 [Serializable]
1498 public class ExecutePackageBeginEventArgs : CancellableHResultEventArgs
1499 {
1500 /// <summary>
1501 /// Creates a new instance of the <see cref="ExecutePackageBeginEventArgs"/> class.
1502 /// </summary>
1503 /// <param name="packageId">The identity of the package to act on.</param>
1504 /// <param name="shouldExecute">Whether the package should really be acted on.</param>
1505 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
1506 public ExecutePackageBeginEventArgs(string packageId, bool shouldExecute, bool cancelRecommendation)
1507 : base(cancelRecommendation)
1508 {
1509 this.PackageId = packageId;
1510 this.ShouldExecute = shouldExecute;
1511 }
1512
1513 /// <summary>
1514 /// Gets the identity of the package to act on.
1515 /// </summary>
1516 public string PackageId { get; private set; }
1517
1518 /// <summary>
1519 /// Gets whether the package should really be acted on.
1520 /// </summary>
1521 public bool ShouldExecute { get; private set; }
1522 }
1523
1524 /// <summary>
1525 /// Additional arguments used when the engine executes one or more patches targeting a product.
1526 /// </summary>
1527 [Serializable]
1528 public class ExecutePatchTargetEventArgs : CancellableHResultEventArgs
1529 {
1530 /// <summary>
1531 /// Creates a new instance of the <see cref="ExecutePatchTargetEventArgs"/> class.
1532 /// </summary>
1533 /// <param name="packageId">The identity of the package to act on.</param>
1534 /// <param name="targetProductCode">The product code of the target of the patch.</param>
1535 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
1536 public ExecutePatchTargetEventArgs(string packageId, string targetProductCode, bool cancelRecommendation)
1537 : base(cancelRecommendation)
1538 {
1539 this.PackageId = packageId;
1540 this.TargetProductCode = targetProductCode;
1541 }
1542
1543 /// <summary>
1544 /// Gets the identity of the package to act on.
1545 /// </summary>
1546 public string PackageId { get; private set; }
1547
1548 /// <summary>
1549 /// Gets the product code being targeted.
1550 /// </summary>
1551 public string TargetProductCode { get; private set; }
1552 }
1553
1554 /// <summary>
1555 /// Additional arguments used when Windows Installer sends an installation message.
1556 /// </summary>
1557 [Serializable]
1558 public class ExecuteMsiMessageEventArgs : ResultEventArgs
1559 {
1560 /// <summary>
1561 /// Creates a new instance of the <see cref="ExecuteMsiMessageEventArgs"/> class.
1562 /// </summary>
1563 /// <param name="packageId">The identity of the package that yielded this message.</param>
1564 /// <param name="messageType">The type of this message.</param>
1565 /// <param name="dwUIHint">Recommended display flags for this message.</param>
1566 /// <param name="message">The message.</param>
1567 /// <param name="data">The extended data for the message.</param>
1568 /// <param name="recommendation">Recommended result from engine.</param>
1569 /// <param name="result">The result to return to the engine.</param>
1570 public ExecuteMsiMessageEventArgs(string packageId, InstallMessage messageType, int dwUIHint, string message, string[] data, Result recommendation, Result result)
1571 : base(recommendation, result)
1572 {
1573 this.PackageId = packageId;
1574 this.MessageType = messageType;
1575 this.UIHint = dwUIHint;
1576 this.Message = message;
1577 this.Data = new ReadOnlyCollection<string>(data ?? new string[] { });
1578 }
1579
1580 /// <summary>
1581 /// Gets the identity of the package that yielded this message.
1582 /// </summary>
1583 public string PackageId { get; private set; }
1584
1585 /// <summary>
1586 /// Gets the type of this message.
1587 /// </summary>
1588 public InstallMessage MessageType { get; private set; }
1589
1590 /// <summary>
1591 /// Gets the recommended display flags for this message.
1592 /// </summary>
1593 public int UIHint { get; private set; }
1594
1595 /// <summary>
1596 /// Gets the message.
1597 /// </summary>
1598 public string Message { get; private set; }
1599
1600 /// <summary>
1601 /// Gets the extended data for the message.
1602 /// </summary>
1603 public IList<string> Data { get; private set; }
1604 }
1605
1606 /// <summary>
1607 /// Additional arugments used for file in use installation messages.
1608 /// </summary>
1609 [Serializable]
1610 public class ExecuteFilesInUseEventArgs : ResultEventArgs
1611 {
1612 /// <summary>
1613 /// Creates a new instance of the <see cref="ExecuteFilesInUseEventArgs"/> class.
1614 /// </summary>
1615 /// <param name="packageId">The identity of the package that yielded the files in use message.</param>
1616 /// <param name="files">The list of files in use.</param>
1617 /// <param name="recommendation">Recommended result from engine.</param>
1618 /// <param name="result">The result to return to the engine.</param>
1619 public ExecuteFilesInUseEventArgs(string packageId, string[] files, Result recommendation, Result result)
1620 : base(recommendation, result)
1621 {
1622 this.PackageId = packageId;
1623 this.Files = new ReadOnlyCollection<string>(files ?? new string[] { });
1624 }
1625
1626 /// <summary>
1627 /// Gets the identity of the package that yielded the files in use message.
1628 /// </summary>
1629 public string PackageId { get; private set; }
1630
1631 /// <summary>
1632 /// Gets the list of files in use.
1633 /// </summary>
1634 public IList<string> Files { get; private set; }
1635 }
1636
1637 /// <summary>
1638 /// Additional arguments used when the engine has completed installing a specific package.
1639 /// </summary>
1640 [Serializable]
1641 public class ExecutePackageCompleteEventArgs : ActionEventArgs<BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION>
1642 {
1643 /// <summary>
1644 /// Creates a new instance of the <see cref="ExecutePackageCompleteEventArgs"/> class.
1645 /// </summary>
1646 /// <param name="packageId">The identity of the package that was acted on.</param>
1647 /// <param name="hrStatus">The return code of the operation.</param>
1648 /// <param name="restart">Whether a restart is required.</param>
1649 /// <param name="recommendation">Recommended action from engine.</param>
1650 /// <param name="action">The action to perform.</param>
1651 public ExecutePackageCompleteEventArgs(string packageId, int hrStatus, ApplyRestart restart, BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION recommendation, BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION action)
1652 : base(hrStatus, recommendation, action)
1653 {
1654 this.PackageId = packageId;
1655 this.Restart = restart;
1656 }
1657
1658 /// <summary>
1659 /// Gets the identity of the package that was acted on.
1660 /// </summary>
1661 public string PackageId { get; private set; }
1662
1663 /// <summary>
1664 /// Gets the package restart state after being applied.
1665 /// </summary>
1666 public ApplyRestart Restart { get; private set; }
1667 }
1668
1669 /// <summary>
1670 /// Additional arguments used when the engine has completed installing packages.
1671 /// </summary>
1672 [Serializable]
1673 public class ExecuteCompleteEventArgs : StatusEventArgs
1674 {
1675 /// <summary>
1676 /// Creates a new instance of the <see cref="ExecuteCompleteEventArgs"/> class.
1677 /// </summary>
1678 /// <param name="hrStatus">The return code of the operation.</param>
1679 public ExecuteCompleteEventArgs(int hrStatus)
1680 : base(hrStatus)
1681 {
1682 }
1683 }
1684
1685 /// <summary>
1686 /// Additional arguments used when the engine has completed installing the bundle.
1687 /// </summary>
1688 [Serializable]
1689 public class ApplyCompleteEventArgs : ActionEventArgs<BOOTSTRAPPER_APPLYCOMPLETE_ACTION>
1690 {
1691 /// <summary>
1692 /// Creates a new instance of the <see cref="ApplyCompleteEventArgs"/> clas.
1693 /// </summary>
1694 /// <param name="hrStatus">The return code of the operation.</param>
1695 /// <param name="restart">Whether a restart is required.</param>
1696 /// <param name="recommendation">Recommended action from engine.</param>
1697 /// <param name="action">The action to perform.</param>
1698 public ApplyCompleteEventArgs(int hrStatus, ApplyRestart restart, BOOTSTRAPPER_APPLYCOMPLETE_ACTION recommendation, BOOTSTRAPPER_APPLYCOMPLETE_ACTION action)
1699 : base(hrStatus, recommendation, action)
1700 {
1701 this.Restart = restart;
1702 }
1703
1704 /// <summary>
1705 /// Gets the apply restart state when complete.
1706 /// </summary>
1707 public ApplyRestart Restart { get; private set; }
1708 }
1709
1710 /// <summary>
1711 /// Additional arguments used by the engine to allow the BA to change the source
1712 /// using <see cref="Engine.SetLocalSource"/> or <see cref="Engine.SetDownloadSource"/>.
1713 /// </summary>
1714 [Serializable]
1715 public class ResolveSourceEventArgs : CancellableHResultEventArgs
1716 {
1717 /// <summary>
1718 /// Creates a new instance of the <see cref="ResolveSourceEventArgs"/> class.
1719 /// </summary>
1720 /// <param name="packageOrContainerId">The identity of the package or container that requires source.</param>
1721 /// <param name="payloadId">The identity of the payload that requires source.</param>
1722 /// <param name="localSource">The current path used for source resolution.</param>
1723 /// <param name="downloadSource">Optional URL to download container or payload.</param>
1724 /// <param name="recommendation">The recommended action from the engine.</param>
1725 /// <param name="action">The action to perform.</param>
1726 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
1727 public ResolveSourceEventArgs(string packageOrContainerId, string payloadId, string localSource, string downloadSource, BOOTSTRAPPER_RESOLVESOURCE_ACTION recommendation, BOOTSTRAPPER_RESOLVESOURCE_ACTION action, bool cancelRecommendation)
1728 : base(cancelRecommendation)
1729 {
1730 this.PackageOrContainerId = packageOrContainerId;
1731 this.PayloadId = payloadId;
1732 this.LocalSource = localSource;
1733 this.DownloadSource = downloadSource;
1734 this.Recommendation = recommendation;
1735 this.Action = action;
1736 }
1737
1738 /// <summary>
1739 /// Gets the identity of the package or container that requires source.
1740 /// </summary>
1741 public string PackageOrContainerId { get; private set; }
1742
1743 /// <summary>
1744 /// Gets the identity of the payload that requires source.
1745 /// </summary>
1746 public string PayloadId { get; private set; }
1747
1748 /// <summary>
1749 /// Gets the current path used for source resolution.
1750 /// </summary>
1751 public string LocalSource { get; private set; }
1752
1753 /// <summary>
1754 /// Gets the optional URL to download container or payload.
1755 /// </summary>
1756 public string DownloadSource { get; private set; }
1757
1758 /// <summary>
1759 /// Gets the recommended action from the engine.
1760 /// </summary>
1761 public BOOTSTRAPPER_RESOLVESOURCE_ACTION Recommendation { get; private set; }
1762
1763 /// <summary>
1764 /// Gets or sets the action to perform.
1765 /// </summary>
1766 public BOOTSTRAPPER_RESOLVESOURCE_ACTION Action { get; set; }
1767 }
1768
1769 /// <summary>
1770 /// Additional arguments used by the engine when it has begun caching a specific package.
1771 /// </summary>
1772 [Serializable]
1773 public class CachePackageBeginEventArgs : CancellableHResultEventArgs
1774 {
1775 /// <summary>
1776 /// Creates a new instance of the <see cref="CachePackageBeginEventArgs"/> class.
1777 /// </summary>
1778 /// <param name="packageId">The identity of the package that is being cached.</param>
1779 /// <param name="cachePayloads">Number of payloads to be cached.</param>
1780 /// <param name="packageCacheSize">The size on disk required by the specific package.</param>
1781 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
1782 public CachePackageBeginEventArgs(string packageId, int cachePayloads, long packageCacheSize, bool cancelRecommendation)
1783 : base(cancelRecommendation)
1784 {
1785 this.PackageId = packageId;
1786 this.CachePayloads = cachePayloads;
1787 this.PackageCacheSize = packageCacheSize;
1788 }
1789
1790 /// <summary>
1791 /// Gets the identity of the package that is being cached.
1792 /// </summary>
1793 public string PackageId { get; private set; }
1794
1795 /// <summary>
1796 /// Gets number of payloads to be cached.
1797 /// </summary>
1798 public long CachePayloads { get; private set; }
1799
1800 /// <summary>
1801 /// Gets the size on disk required by the specific package.
1802 /// </summary>
1803 public long PackageCacheSize { get; private set; }
1804 }
1805
1806 /// <summary>
1807 /// Additional arguments passed by the engine when it has completed caching a specific package.
1808 /// </summary>
1809 [Serializable]
1810 public class CachePackageCompleteEventArgs : ActionEventArgs<BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION>
1811 {
1812 /// <summary>
1813 /// Creates a new instance of the <see cref="CachePackageCompleteEventArgs"/> class.
1814 /// </summary>
1815 /// <param name="packageId">The identity of the package that was cached.</param>
1816 /// <param name="hrStatus">The return code of the operation.</param>
1817 /// <param name="recommendation">Recommended action from engine.</param>
1818 /// <param name="action">The action to perform.</param>
1819 public CachePackageCompleteEventArgs(string packageId, int hrStatus, BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION recommendation, BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION action)
1820 : base(hrStatus, recommendation, action)
1821 {
1822 this.PackageId = packageId;
1823 }
1824
1825 /// <summary>
1826 /// Gets the identity of the package that was cached.
1827 /// </summary>
1828 public string PackageId { get; private set; }
1829 }
1830
1831 /// <summary>
1832 /// Additional arguments passed by the engine while executing on payload.
1833 /// </summary>
1834 [Serializable]
1835 public class ExecuteProgressEventArgs : CancellableHResultEventArgs
1836 {
1837 /// <summary>
1838 /// Creates a new instance of the <see cref="ExecuteProgressEventArgs"/> class.
1839 /// </summary>
1840 /// <param name="packageId">The identifier of the package being executed.</param>
1841 /// <param name="progressPercentage">The percentage from 0 to 100 of the execution progress for a single payload.</param>
1842 /// <param name="overallPercentage">The percentage from 0 to 100 of the execution progress for all payload.</param>
1843 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
1844 public ExecuteProgressEventArgs(string packageId, int progressPercentage, int overallPercentage, bool cancelRecommendation)
1845 : base(cancelRecommendation)
1846 {
1847 this.PackageId = packageId;
1848 this.ProgressPercentage = progressPercentage;
1849 this.OverallPercentage = overallPercentage;
1850 }
1851
1852 /// <summary>
1853 /// Gets the identity of the package that was executed.
1854 /// </summary>
1855 public string PackageId { get; private set; }
1856
1857 /// <summary>
1858 /// Gets the percentage from 0 to 100 of the execution progress for a single payload.
1859 /// </summary>
1860 public int ProgressPercentage { get; private set; }
1861
1862 /// <summary>
1863 /// Gets the percentage from 0 to 100 of the execution progress for all payloads.
1864 /// </summary>
1865 public int OverallPercentage { get; private set; }
1866 }
1867
1868 /// <summary>
1869 /// Additional arguments passed by the engine before it tries to launch the preapproved executable.
1870 /// </summary>
1871 [Serializable]
1872 public class LaunchApprovedExeBeginArgs : CancellableHResultEventArgs
1873 {
1874 public LaunchApprovedExeBeginArgs(bool cancelRecommendation)
1875 : base(cancelRecommendation)
1876 {
1877 }
1878 }
1879
1880 /// <summary>
1881 /// Additional arguments passed by the engine after it finished trying to launch the preapproved executable.
1882 /// </summary>
1883 [Serializable]
1884 public class LaunchApprovedExeCompleteArgs : StatusEventArgs
1885 {
1886 private int processId;
1887
1888 public LaunchApprovedExeCompleteArgs(int hrStatus, int processId)
1889 : base(hrStatus)
1890 {
1891 this.processId = processId;
1892 }
1893
1894 /// <summary>
1895 /// Gets the ProcessId of the process that was launched.
1896 /// This is only valid if the status reports success.
1897 /// </summary>
1898 public int ProcessId
1899 {
1900 get { return this.processId; }
1901 }
1902 }
1903}
diff --git a/src/WixToolset.Mba.Core/Exceptions.cs b/src/WixToolset.Mba.Core/Exceptions.cs
new file mode 100644
index 00000000..360b360d
--- /dev/null
+++ b/src/WixToolset.Mba.Core/Exceptions.cs
@@ -0,0 +1,145 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.Runtime.Serialization;
7
8 /// <summary>
9 /// Base class for exception returned to the bootstrapper application host.
10 /// </summary>
11 [Serializable]
12 public abstract class BootstrapperException : Exception
13 {
14 /// <summary>
15 /// Creates an instance of the <see cref="BootstrapperException"/> base class with the given HRESULT.
16 /// </summary>
17 /// <param name="hr">The HRESULT for the exception that is used by the bootstrapper application host.</param>
18 public BootstrapperException(int hr)
19 {
20 this.HResult = hr;
21 }
22
23 /// <summary>
24 /// Initializes a new instance of the <see cref="BootstrapperException"/> class.
25 /// </summary>
26 /// <param name="message">Exception message.</param>
27 public BootstrapperException(string message)
28 : base(message)
29 {
30 }
31
32 /// <summary>
33 /// Initializes a new instance of the <see cref="BootstrapperException"/> class.
34 /// </summary>
35 /// <param name="message">Exception message</param>
36 /// <param name="innerException">Inner exception associated with this one</param>
37 public BootstrapperException(string message, Exception innerException)
38 : base(message, innerException)
39 {
40 }
41
42 /// <summary>
43 /// Initializes a new instance of the <see cref="BootstrapperException"/> class.
44 /// </summary>
45 /// <param name="info">Serialization information for this exception</param>
46 /// <param name="context">Streaming context to serialize to</param>
47 protected BootstrapperException(SerializationInfo info, StreamingContext context)
48 : base(info, context)
49 {
50 }
51 }
52
53 /// <summary>
54 /// The bootstrapper application assembly loaded by the host does not contain exactly one instance of the
55 /// <see cref="BootstrapperApplicationFactoryAttribute"/> class.
56 /// </summary>
57 /// <seealso cref="BootstrapperApplicationFactoryAttribute"/>
58 [Serializable]
59 public class MissingAttributeException : BootstrapperException
60 {
61 /// <summary>
62 /// Creates a new instance of the <see cref="MissingAttributeException"/> class.
63 /// </summary>
64 public MissingAttributeException()
65 : base(NativeMethods.E_NOTFOUND)
66 {
67 }
68
69 /// <summary>
70 /// Initializes a new instance of the <see cref="MissingAttributeException"/> class.
71 /// </summary>
72 /// <param name="message">Exception message.</param>
73 public MissingAttributeException(string message)
74 : base(message)
75 {
76 }
77
78 /// <summary>
79 /// Initializes a new instance of the <see cref="MissingAttributeException"/> class.
80 /// </summary>
81 /// <param name="message">Exception message</param>
82 /// <param name="innerException">Inner exception associated with this one</param>
83 public MissingAttributeException(string message, Exception innerException)
84 : base(message, innerException)
85 {
86 }
87
88 /// <summary>
89 /// Initializes a new instance of the <see cref="MissingAttributeException"/> class.
90 /// </summary>
91 /// <param name="info">Serialization information for this exception</param>
92 /// <param name="context">Streaming context to serialize to</param>
93 protected MissingAttributeException(SerializationInfo info, StreamingContext context)
94 : base(info, context)
95 {
96 }
97 }
98
99 /// <summary>
100 /// The bootstrapper application factory specified by the <see cref="BootstrapperApplicationFactoryAttribute"/>
101 /// does not extend the <see cref="IBootstrapperApplicationFactory"/> base class.
102 /// </summary>
103 /// <seealso cref="BaseBootstrapperApplicationFactory"/>
104 /// <seealso cref="BootstrapperApplicationFactoryAttribute"/>
105 [Serializable]
106 public class InvalidBootstrapperApplicationFactoryException : BootstrapperException
107 {
108 /// <summary>
109 /// Creates a new instance of the <see cref="InvalidBootstrapperApplicationFactoryException"/> class.
110 /// </summary>
111 public InvalidBootstrapperApplicationFactoryException()
112 : base(NativeMethods.E_UNEXPECTED)
113 {
114 }
115
116 /// <summary>
117 /// Initializes a new instance of the <see cref="InvalidBootstrapperApplicationFactoryException"/> class.
118 /// </summary>
119 /// <param name="message">Exception message.</param>
120 public InvalidBootstrapperApplicationFactoryException(string message)
121 : base(message)
122 {
123 }
124
125 /// <summary>
126 /// Initializes a new instance of the <see cref="InvalidBootstrapperApplicationFactoryException"/> class.
127 /// </summary>
128 /// <param name="message">Exception message</param>
129 /// <param name="innerException">Inner exception associated with this one</param>
130 public InvalidBootstrapperApplicationFactoryException(string message, Exception innerException)
131 : base(message, innerException)
132 {
133 }
134
135 /// <summary>
136 /// Initializes a new instance of the <see cref="InvalidBootstrapperApplicationFactoryException"/> class.
137 /// </summary>
138 /// <param name="info">Serialization information for this exception</param>
139 /// <param name="context">Streaming context to serialize to</param>
140 protected InvalidBootstrapperApplicationFactoryException(SerializationInfo info, StreamingContext context)
141 : base(info, context)
142 {
143 }
144 }
145}
diff --git a/src/WixToolset.Mba.Core/HostSection.cs b/src/WixToolset.Mba.Core/HostSection.cs
new file mode 100644
index 00000000..e5b7ea64
--- /dev/null
+++ b/src/WixToolset.Mba.Core/HostSection.cs
@@ -0,0 +1,47 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.Configuration;
7
8 /// <summary>
9 /// Handler for the Host configuration section.
10 /// </summary>
11 public sealed class HostSection : ConfigurationSection
12 {
13 private static readonly ConfigurationProperty assemblyNameProperty = new ConfigurationProperty("assemblyName", typeof(string), null, ConfigurationPropertyOptions.IsRequired);
14 private static readonly ConfigurationProperty supportedFrameworksProperty = new ConfigurationProperty("", typeof(SupportedFrameworkElementCollection), null, ConfigurationPropertyOptions.IsDefaultCollection);
15
16 /// <summary>
17 /// Creates a new instance of the <see cref="HostSection"/> class.
18 /// </summary>
19 public HostSection()
20 {
21 }
22
23 /// <summary>
24 /// Gets the name of the assembly that contians the <see cref="BootstrapperApplication"/> child class.
25 /// </summary>
26 /// <remarks>
27 /// The assembly specified by this name must contain the <see cref="BootstrapperApplicationFactoryAttribute"/> to identify
28 /// the type of the <see cref="BootstrapperApplication"/> child class.
29 /// </remarks>
30 [ConfigurationProperty("assemblyName", IsRequired = true)]
31 public string AssemblyName
32 {
33 get { return (string)base[assemblyNameProperty]; }
34 set { base[assemblyNameProperty] = value; }
35 }
36
37 /// <summary>
38 /// Gets the <see cref="SupportedFrameworkElementCollection"/> of supported frameworks for the host configuration.
39 /// </summary>
40 [ConfigurationProperty("", IsDefaultCollection = true)]
41 [ConfigurationCollection(typeof(SupportedFrameworkElement))]
42 public SupportedFrameworkElementCollection SupportedFrameworks
43 {
44 get { return (SupportedFrameworkElementCollection)base[supportedFrameworksProperty]; }
45 }
46 }
47}
diff --git a/src/WixToolset.Mba.Core/IBootstrapperApplicationData.cs b/src/WixToolset.Mba.Core/IBootstrapperApplicationData.cs
new file mode 100644
index 00000000..c8c6e6e3
--- /dev/null
+++ b/src/WixToolset.Mba.Core/IBootstrapperApplicationData.cs
@@ -0,0 +1,12 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System.IO;
6
7 public interface IBootstrapperApplicationData
8 {
9 FileInfo BADataFile { get; }
10 IBundleInfo Bundle { get; }
11 }
12} \ No newline at end of file
diff --git a/src/WixToolset.Mba.Core/IBootstrapperApplicationFactory.cs b/src/WixToolset.Mba.Core/IBootstrapperApplicationFactory.cs
new file mode 100644
index 00000000..414d28ed
--- /dev/null
+++ b/src/WixToolset.Mba.Core/IBootstrapperApplicationFactory.cs
@@ -0,0 +1,52 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.CodeDom.Compiler;
7 using System.Runtime.InteropServices;
8
9 [ComVisible(true)]
10 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
11 [Guid("2965A12F-AC7B-43A0-85DF-E4B2168478A4")]
12 [GeneratedCodeAttribute("WixToolset.Bootstrapper.InteropCodeGenerator", "1.0.0.0")]
13 public interface IBootstrapperApplicationFactory
14 {
15 IBootstrapperApplication Create(
16 [MarshalAs(UnmanagedType.Interface)] IBootstrapperEngine pEngine,
17 ref Command command
18 );
19 }
20
21 [Serializable]
22 [StructLayout(LayoutKind.Sequential)]
23 [GeneratedCodeAttribute("WixToolset.Bootstrapper.InteropCodeGenerator", "1.0.0.0")]
24 public struct Command
25 {
26 [MarshalAs(UnmanagedType.U4)] private readonly LaunchAction action;
27 [MarshalAs(UnmanagedType.U4)] private readonly Display display;
28 [MarshalAs(UnmanagedType.U4)] private readonly Restart restart;
29 [MarshalAs(UnmanagedType.LPWStr)] private readonly string wzCommandLine;
30 [MarshalAs(UnmanagedType.I4)] private readonly int nCmdShow;
31 [MarshalAs(UnmanagedType.U4)] private readonly ResumeType resume;
32 private readonly IntPtr hwndSplashScreen;
33 [MarshalAs(UnmanagedType.I4)] private readonly RelationType relation;
34 [MarshalAs(UnmanagedType.Bool)] private readonly bool passthrough;
35 [MarshalAs(UnmanagedType.LPWStr)] private readonly string wzLayoutDirectory;
36
37 public IBootstrapperCommand GetBootstrapperCommand()
38 {
39 return new BootstrapperCommand(
40 this.action,
41 this.display,
42 this.restart,
43 this.wzCommandLine,
44 this.nCmdShow,
45 this.resume,
46 this.hwndSplashScreen,
47 this.relation,
48 this.passthrough,
49 this.wzLayoutDirectory);
50 }
51 }
52}
diff --git a/src/WixToolset.Mba.Core/IBootstrapperCommand.cs b/src/WixToolset.Mba.Core/IBootstrapperCommand.cs
new file mode 100644
index 00000000..332b4c3b
--- /dev/null
+++ b/src/WixToolset.Mba.Core/IBootstrapperCommand.cs
@@ -0,0 +1,63 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6
7 /// <summary>
8 /// Command information passed from the engine for the BA to perform.
9 /// </summary>
10 public interface IBootstrapperCommand
11 {
12 /// <summary>
13 /// Gets the action for the BA to perform.
14 /// </summary>
15 LaunchAction Action { get; }
16
17 /// <summary>
18 /// Gets the display level for the BA.
19 /// </summary>
20 Display Display { get; }
21
22 /// <summary>
23 /// Gets the action to perform if a reboot is required.
24 /// </summary>
25 Restart Restart { get; }
26
27 /// <summary>
28 /// Gets the command line arguments as a string array.
29 /// </summary>
30 /// <returns>
31 /// Array of command line arguments not handled by the engine.
32 /// </returns>
33 /// <exception type="Win32Exception">The command line could not be parsed into an array.</exception>
34 string[] CommandLineArgs { get; }
35
36 int CmdShow { get; }
37
38 /// <summary>
39 /// Gets the method of how the engine was resumed from a previous installation step.
40 /// </summary>
41 ResumeType Resume { get; }
42
43 /// <summary>
44 /// Gets the handle to the splash screen window. If no splash screen was displayed this value will be IntPtr.Zero.
45 /// </summary>
46 IntPtr SplashScreen { get; }
47
48 /// <summary>
49 /// If this was run from a related bundle, specifies the relation type.
50 /// </summary>
51 RelationType Relation { get; }
52
53 /// <summary>
54 /// If this was run from a backward compatible bundle.
55 /// </summary>
56 bool Passthrough { get; }
57
58 /// <summary>
59 /// Gets layout directory.
60 /// </summary>
61 string LayoutDirectory { get; }
62 }
63}
diff --git a/src/WixToolset.Mba.Core/IBundleInfo.cs b/src/WixToolset.Mba.Core/IBundleInfo.cs
new file mode 100644
index 00000000..a5f4b9c7
--- /dev/null
+++ b/src/WixToolset.Mba.Core/IBundleInfo.cs
@@ -0,0 +1,16 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System.Collections.Generic;
6
7 public interface IBundleInfo
8 {
9 string LogVariable { get; }
10 string Name { get; }
11 IDictionary<string, IPackageInfo> Packages { get; }
12 bool PerMachine { get; }
13
14 void AddRelatedBundleAsPackage(DetectRelatedBundleEventArgs e);
15 }
16} \ No newline at end of file
diff --git a/src/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs b/src/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs
new file mode 100644
index 00000000..ccbe84db
--- /dev/null
+++ b/src/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs
@@ -0,0 +1,65 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6
7 public interface IDefaultBootstrapperApplication : IBootstrapperApplication
8 {
9 event EventHandler<ApplyBeginEventArgs> ApplyBegin;
10 event EventHandler<ApplyCompleteEventArgs> ApplyComplete;
11 event EventHandler<CacheAcquireBeginEventArgs> CacheAcquireBegin;
12 event EventHandler<CacheAcquireCompleteEventArgs> CacheAcquireComplete;
13 event EventHandler<CacheAcquireProgressEventArgs> CacheAcquireProgress;
14 event EventHandler<CacheBeginEventArgs> CacheBegin;
15 event EventHandler<CacheCompleteEventArgs> CacheComplete;
16 event EventHandler<CachePackageBeginEventArgs> CachePackageBegin;
17 event EventHandler<CachePackageCompleteEventArgs> CachePackageComplete;
18 event EventHandler<CacheVerifyBeginEventArgs> CacheVerifyBegin;
19 event EventHandler<CacheVerifyCompleteEventArgs> CacheVerifyComplete;
20 event EventHandler<DetectBeginEventArgs> DetectBegin;
21 event EventHandler<DetectCompatibleMsiPackageEventArgs> DetectCompatibleMsiPackage;
22 event EventHandler<DetectCompleteEventArgs> DetectComplete;
23 event EventHandler<DetectForwardCompatibleBundleEventArgs> DetectForwardCompatibleBundle;
24 event EventHandler<DetectMsiFeatureEventArgs> DetectMsiFeature;
25 event EventHandler<DetectPackageBeginEventArgs> DetectPackageBegin;
26 event EventHandler<DetectPackageCompleteEventArgs> DetectPackageComplete;
27 event EventHandler<DetectRelatedBundleEventArgs> DetectRelatedBundle;
28 event EventHandler<DetectRelatedMsiPackageEventArgs> DetectRelatedMsiPackage;
29 event EventHandler<DetectTargetMsiPackageEventArgs> DetectTargetMsiPackage;
30 event EventHandler<DetectUpdateEventArgs> DetectUpdate;
31 event EventHandler<DetectUpdateBeginEventArgs> DetectUpdateBegin;
32 event EventHandler<DetectUpdateCompleteEventArgs> DetectUpdateComplete;
33 event EventHandler<ElevateBeginEventArgs> ElevateBegin;
34 event EventHandler<ElevateCompleteEventArgs> ElevateComplete;
35 event EventHandler<ErrorEventArgs> Error;
36 event EventHandler<ExecuteBeginEventArgs> ExecuteBegin;
37 event EventHandler<ExecuteCompleteEventArgs> ExecuteComplete;
38 event EventHandler<ExecuteFilesInUseEventArgs> ExecuteFilesInUse;
39 event EventHandler<ExecuteMsiMessageEventArgs> ExecuteMsiMessage;
40 event EventHandler<ExecutePackageBeginEventArgs> ExecutePackageBegin;
41 event EventHandler<ExecutePackageCompleteEventArgs> ExecutePackageComplete;
42 event EventHandler<ExecutePatchTargetEventArgs> ExecutePatchTarget;
43 event EventHandler<ExecuteProgressEventArgs> ExecuteProgress;
44 event EventHandler<LaunchApprovedExeBeginArgs> LaunchApprovedExeBegin;
45 event EventHandler<LaunchApprovedExeCompleteArgs> LaunchApprovedExeComplete;
46 event EventHandler<PlanBeginEventArgs> PlanBegin;
47 event EventHandler<PlanCompatibleMsiPackageBeginEventArgs> PlanCompatibleMsiPackageBegin;
48 event EventHandler<PlanCompatibleMsiPackageCompleteEventArgs> PlanCompatibleMsiPackageComplete;
49 event EventHandler<PlanCompleteEventArgs> PlanComplete;
50 event EventHandler<PlanMsiFeatureEventArgs> PlanMsiFeature;
51 event EventHandler<PlanPackageBeginEventArgs> PlanPackageBegin;
52 event EventHandler<PlanPackageCompleteEventArgs> PlanPackageComplete;
53 event EventHandler<PlanRelatedBundleEventArgs> PlanRelatedBundle;
54 event EventHandler<PlanTargetMsiPackageEventArgs> PlanTargetMsiPackage;
55 event EventHandler<ProgressEventArgs> Progress;
56 event EventHandler<RegisterBeginEventArgs> RegisterBegin;
57 event EventHandler<RegisterCompleteEventArgs> RegisterComplete;
58 event EventHandler<ResolveSourceEventArgs> ResolveSource;
59 event EventHandler<ShutdownEventArgs> Shutdown;
60 event EventHandler<StartupEventArgs> Startup;
61 event EventHandler<SystemShutdownEventArgs> SystemShutdown;
62 event EventHandler<UnregisterBeginEventArgs> UnregisterBegin;
63 event EventHandler<UnregisterCompleteEventArgs> UnregisterComplete;
64 }
65} \ No newline at end of file
diff --git a/src/WixToolset.Mba.Core/IEngine.cs b/src/WixToolset.Mba.Core/IEngine.cs
new file mode 100644
index 00000000..46b8158a
--- /dev/null
+++ b/src/WixToolset.Mba.Core/IEngine.cs
@@ -0,0 +1,176 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.ComponentModel;
7 using System.Security;
8
9 public interface IEngine
10 {
11 /// <summary>
12 /// Gets or sets numeric variables for the engine.
13 /// </summary>
14 IVariables<long> NumericVariables { get; }
15
16 /// <summary>
17 /// Gets the number of packages in the bundle.
18 /// </summary>
19 int PackageCount { get; }
20
21 /// <summary>
22 /// Gets or sets string variables for the engine using SecureStrings.
23 /// </summary>
24 IVariables<SecureString> SecureStringVariables { get; }
25
26 /// <summary>
27 /// Gets or sets string variables for the engine.
28 /// </summary>
29 IVariables<string> StringVariables { get; }
30
31 /// <summary>
32 /// Gets or sets <see cref="Version"/> variables for the engine.
33 ///
34 /// The <see cref="Version"/> class can keep track of when the build and revision fields are undefined, but the engine can't.
35 /// Therefore, the build and revision fields must be defined when setting a <see cref="Version"/> variable.
36 /// Use the NormalizeVersion method to make sure the engine can accept the Version.
37 ///
38 /// To keep track of versions without build or revision fields, use StringVariables instead.
39 /// </summary>
40 /// <exception cref="OverflowException">The given <see cref="Version"/> was invalid.</exception>
41 IVariables<Version> VersionVariables { get; }
42
43 /// <summary>
44 /// Install the packages.
45 /// </summary>
46 /// <param name="hwndParent">The parent window for the installation user interface.</param>
47 void Apply(IntPtr hwndParent);
48
49 /// <summary>
50 /// Close the splash screen if it is still open. Does nothing if the splash screen is not or
51 /// never was opened.
52 /// </summary>
53 void CloseSplashScreen();
54
55 /// <summary>
56 /// Determine if all installation conditions are fulfilled.
57 /// </summary>
58 void Detect();
59
60 /// <summary>
61 /// Determine if all installation conditions are fulfilled.
62 /// </summary>
63 /// <param name="hwndParent">The parent window for the installation user interface.</param>
64 void Detect(IntPtr hwndParent);
65
66 /// <summary>
67 /// Elevate the install.
68 /// </summary>
69 /// <param name="hwndParent">The parent window of the elevation dialog.</param>
70 /// <returns>true if elevation succeeded; otherwise, false if the user cancelled.</returns>
71 /// <exception cref="Win32Exception">A Win32 error occurred.</exception>
72 bool Elevate(IntPtr hwndParent);
73
74 /// <summary>
75 /// Escapes the input string.
76 /// </summary>
77 /// <param name="input">The string to escape.</param>
78 /// <returns>The escaped string.</returns>
79 /// <exception cref="Win32Exception">A Win32 error occurred.</exception>
80 string EscapeString(string input);
81
82 /// <summary>
83 /// Evaluates the <paramref name="condition"/> string.
84 /// </summary>
85 /// <param name="condition">The string representing the condition to evaluate.</param>
86 /// <returns>Whether the condition evaluated to true or false.</returns>
87 bool EvaluateCondition(string condition);
88
89 /// <summary>
90 /// Formats the input string.
91 /// </summary>
92 /// <param name="format">The string to format.</param>
93 /// <returns>The formatted string.</returns>
94 /// <exception cref="Win32Exception">A Win32 error occurred.</exception>
95 string FormatString(string format);
96
97 /// <summary>
98 /// Launches a preapproved executable elevated. As long as the engine already elevated, there will be no UAC prompt.
99 /// </summary>
100 /// <param name="hwndParent">The parent window of the elevation dialog (if the engine hasn't elevated yet).</param>
101 /// <param name="approvedExeForElevationId">Id of the ApprovedExeForElevation element specified when the bundle was authored.</param>
102 /// <param name="arguments">Optional arguments.</param>
103 void LaunchApprovedExe(IntPtr hwndParent, string approvedExeForElevationId, string arguments);
104
105 /// <summary>
106 /// Launches a preapproved executable elevated. As long as the engine already elevated, there will be no UAC prompt.
107 /// </summary>
108 /// <param name="hwndParent">The parent window of the elevation dialog (if the engine hasn't elevated yet).</param>
109 /// <param name="approvedExeForElevationId">Id of the ApprovedExeForElevation element specified when the bundle was authored.</param>
110 /// <param name="arguments">Optional arguments.</param>
111 /// <param name="waitForInputIdleTimeout">Timeout in milliseconds. When set to something other than zero, the engine will call WaitForInputIdle for the new process with this timeout before calling OnLaunchApprovedExeComplete.</param>
112 void LaunchApprovedExe(IntPtr hwndParent, string approvedExeForElevationId, string arguments, int waitForInputIdleTimeout);
113
114 /// <summary>
115 /// Logs the <paramref name="message"/>.
116 /// </summary>
117 /// <param name="level">The logging level.</param>
118 /// <param name="message">The message to log.</param>
119 void Log(LogLevel level, string message);
120
121 /// <summary>
122 /// Determine the installation sequencing and costing.
123 /// </summary>
124 /// <param name="action">The action to perform when planning.</param>
125 void Plan(LaunchAction action);
126
127 /// <summary>
128 /// Set the update information for a bundle.
129 /// </summary>
130 /// <param name="localSource">Optional local source path for the update. Default is "update\[OriginalNameOfBundle].exe".</param>
131 /// <param name="downloadSource">Optional download source for the update.</param>
132 /// <param name="size">Size of the expected update.</param>
133 /// <param name="hashType">Type of the hash expected on the update.</param>
134 /// <param name="hash">Optional hash expected for the update.</param>
135 void SetUpdate(string localSource, string downloadSource, long size, UpdateHashType hashType, byte[] hash);
136
137 /// <summary>
138 /// Set the local source for a package or container.
139 /// </summary>
140 /// <param name="packageOrContainerId">The id that uniquely identifies the package or container.</param>
141 /// <param name="payloadId">The id that uniquely identifies the payload.</param>
142 /// <param name="path">The new source path.</param>
143 void SetLocalSource(string packageOrContainerId, string payloadId, string path);
144
145 /// <summary>
146 /// Set the new download URL for a package or container.
147 /// </summary>
148 /// <param name="packageOrContainerId">The id that uniquely identifies the package or container.</param>
149 /// <param name="payloadId">The id that uniquely identifies the payload.</param>
150 /// <param name="url">The new url.</param>
151 /// <param name="user">The user name for proxy authentication.</param>
152 /// <param name="password">The password for proxy authentication.</param>
153 void SetDownloadSource(string packageOrContainerId, string payloadId, string url, string user, string password);
154
155 /// <summary>
156 /// Sends error message when embedded.
157 /// </summary>
158 /// <param name="errorCode">Error code.</param>
159 /// <param name="message">Error message.</param>
160 /// <param name="uiHint">UI buttons to show on error dialog.</param>
161 int SendEmbeddedError(int errorCode, string message, int uiHint);
162
163 /// <summary>
164 /// Sends progress percentages when embedded.
165 /// </summary>
166 /// <param name="progressPercentage">Percentage completed thus far.</param>
167 /// <param name="overallPercentage">Overall percentage completed.</param>
168 int SendEmbeddedProgress(int progressPercentage, int overallPercentage);
169
170 /// <summary>
171 /// Shuts down the engine.
172 /// </summary>
173 /// <param name="exitCode">Exit code indicating reason for shut down.</param>
174 void Quit(int exitCode);
175 }
176}
diff --git a/src/WixToolset.Mba.Core/IPackageInfo.cs b/src/WixToolset.Mba.Core/IPackageInfo.cs
new file mode 100644
index 00000000..f4c7c558
--- /dev/null
+++ b/src/WixToolset.Mba.Core/IPackageInfo.cs
@@ -0,0 +1,20 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 public interface IPackageInfo
6 {
7 CacheType CacheType { get; }
8 string Description { get; }
9 bool DisplayInternalUI { get; }
10 string DisplayName { get; }
11 string Id { get; }
12 string InstallCondition { get; }
13 bool Permanent { get; }
14 string ProductCode { get; }
15 PackageType Type { get; }
16 string UpgradeCode { get; }
17 string Version { get; }
18 bool Vital { get; }
19 }
20} \ No newline at end of file
diff --git a/src/WixToolset.Mba.Core/IVariables.cs b/src/WixToolset.Mba.Core/IVariables.cs
new file mode 100644
index 00000000..15da4c84
--- /dev/null
+++ b/src/WixToolset.Mba.Core/IVariables.cs
@@ -0,0 +1,27 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6
7 /// <summary>
8 /// An accessor for numeric, string, and version variables for the engine.
9 /// </summary>
10 public interface IVariables<T>
11 {
12 /// <summary>
13 /// Gets or sets the variable given by <paramref name="name"/>.
14 /// </summary>
15 /// <param name="name">The name of the variable to get/set.</param>
16 /// <returns>The value of the given variable.</returns>
17 /// <exception cref="Exception">An error occurred getting the variable.</exception>
18 T this[string name] { get; set; }
19
20 /// <summary>
21 /// Gets whether the variable given by <paramref name="name"/> exists.
22 /// </summary>
23 /// <param name="name">The name of the variable to check.</param>
24 /// <returns>True if the variable given by <paramref name="name"/> exists; otherwise, false.</returns>
25 bool Contains(string name);
26 }
27}
diff --git a/src/WixToolset.Mba.Core/NativeMethods.cs b/src/WixToolset.Mba.Core/NativeMethods.cs
new file mode 100644
index 00000000..1964cb45
--- /dev/null
+++ b/src/WixToolset.Mba.Core/NativeMethods.cs
@@ -0,0 +1,37 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.Runtime.InteropServices;
7
8 /// <summary>
9 /// Contains native constants, functions, and structures for this assembly.
10 /// </summary>
11 internal static class NativeMethods
12 {
13 #region Error Constants
14 internal const int S_OK = 0;
15 internal const int E_MOREDATA = unchecked((int)0x800700ea);
16 internal const int E_INSUFFICIENT_BUFFER = unchecked((int)0x8007007a);
17 internal const int E_CANCELLED = unchecked((int)0x800704c7);
18 internal const int E_ALREADYINITIALIZED = unchecked((int)0x800704df);
19 internal const int E_NOTFOUND = unchecked((int)0x80070490);
20 internal const int E_NOTIMPL = unchecked((int)0x80004001);
21 internal const int E_UNEXPECTED = unchecked((int)0x8000ffff);
22 #endregion
23
24 #region Functions
25 [DllImport("shell32.dll", ExactSpelling = true, SetLastError = true)]
26 internal static extern IntPtr CommandLineToArgvW(
27 [MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine,
28 out int pNumArgs
29 );
30
31 [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
32 internal static extern IntPtr LocalFree(
33 IntPtr hMem
34 );
35 #endregion
36 }
37}
diff --git a/src/WixToolset.Mba.Core/PackageInfo.cs b/src/WixToolset.Mba.Core/PackageInfo.cs
new file mode 100644
index 00000000..99ebb33a
--- /dev/null
+++ b/src/WixToolset.Mba.Core/PackageInfo.cs
@@ -0,0 +1,181 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Xml;
8 using System.Xml.XPath;
9
10 public enum CacheType
11 {
12 No,
13 Yes,
14 Always,
15 }
16
17 public enum PackageType
18 {
19 Unknown,
20 Exe,
21 Msi,
22 Msp,
23 Msu,
24 UpgradeBundle,
25 AddonBundle,
26 PatchBundle,
27 }
28
29 public class PackageInfo : IPackageInfo
30 {
31 public string Id { get; internal set; }
32 public string DisplayName { get; internal set; }
33 public string Description { get; internal set; }
34 public PackageType Type { get; internal set; }
35 public bool Permanent { get; internal set; }
36 public bool Vital { get; internal set; }
37 public bool DisplayInternalUI { get; internal set; }
38 public string ProductCode { get; internal set; }
39 public string UpgradeCode { get; internal set; }
40 public string Version { get; internal set; }
41 public string InstallCondition { get; internal set; }
42 public CacheType CacheType { get; internal set; }
43
44 internal PackageInfo() { }
45
46 public static IEnumerable<IPackageInfo> ParsePackagesFromXml(XPathNavigator root)
47 {
48 XmlNamespaceManager namespaceManager = new XmlNamespaceManager(root.NameTable);
49 namespaceManager.AddNamespace("p", BootstrapperApplicationData.XMLNamespace);
50 XPathNodeIterator nodes = root.Select("/p:BootstrapperApplicationData/p:WixPackageProperties", namespaceManager);
51
52 foreach (XPathNavigator node in nodes)
53 {
54 var package = new PackageInfo();
55
56 string id = BootstrapperApplicationData.GetAttribute(node, "Package");
57 if (id == null)
58 {
59 throw new Exception("Failed to get package identifier for package.");
60 }
61 package.Id = id;
62
63 package.DisplayName = BootstrapperApplicationData.GetAttribute(node, "DisplayName");
64
65 package.Description = BootstrapperApplicationData.GetAttribute(node, "Description");
66
67 PackageType? packageType = GetPackageTypeAttribute(node, "PackageType");
68 if (!packageType.HasValue)
69 {
70 throw new Exception("Failed to get package type for package.");
71 }
72 package.Type = packageType.Value;
73
74 bool? permanent = BootstrapperApplicationData.GetYesNoAttribute(node, "Permanent");
75 if (!permanent.HasValue)
76 {
77 throw new Exception("Failed to get permanent settings for package.");
78 }
79 package.Permanent = permanent.Value;
80
81 bool? vital = BootstrapperApplicationData.GetYesNoAttribute(node, "Vital");
82 if (!vital.HasValue)
83 {
84 throw new Exception("Failed to get vital setting for package.");
85 }
86 package.Vital = vital.Value;
87
88 bool? displayInternalUI = BootstrapperApplicationData.GetYesNoAttribute(node, "DisplayInternalUI");
89 package.DisplayInternalUI = displayInternalUI.HasValue && displayInternalUI.Value;
90
91 package.ProductCode = BootstrapperApplicationData.GetAttribute(node, "ProductCode");
92
93 package.UpgradeCode = BootstrapperApplicationData.GetAttribute(node, "UpgradeCode");
94
95 package.Version = BootstrapperApplicationData.GetAttribute(node, "Version");
96
97 package.InstallCondition = BootstrapperApplicationData.GetAttribute(node, "InstallCondition");
98
99 yield return package;
100 }
101 }
102
103 public static CacheType? GetCacheTypeAttribute(XPathNavigator node, string attributeName)
104 {
105 string attributeValue = BootstrapperApplicationData.GetAttribute(node, attributeName);
106
107 if (attributeValue == null)
108 {
109 return null;
110 }
111
112 if (attributeValue.Equals("yes", StringComparison.InvariantCulture))
113 {
114 return CacheType.Yes;
115 }
116 else if (attributeValue.Equals("always", StringComparison.InvariantCulture))
117 {
118 return CacheType.Always;
119 }
120 else
121 {
122 return CacheType.No;
123 }
124 }
125
126 public static PackageType? GetPackageTypeAttribute(XPathNavigator node, string attributeName)
127 {
128 string attributeValue = BootstrapperApplicationData.GetAttribute(node, attributeName);
129
130 if (attributeValue == null)
131 {
132 return null;
133 }
134
135 if (attributeValue.Equals("Exe", StringComparison.InvariantCulture))
136 {
137 return PackageType.Exe;
138 }
139 else if (attributeValue.Equals("Msi", StringComparison.InvariantCulture))
140 {
141 return PackageType.Msi;
142 }
143 else if (attributeValue.Equals("Msp", StringComparison.InvariantCulture))
144 {
145 return PackageType.Msp;
146 }
147 else if (attributeValue.Equals("Msu", StringComparison.InvariantCulture))
148 {
149 return PackageType.Msu;
150 }
151 else
152 {
153 return PackageType.Unknown;
154 }
155 }
156
157 public static PackageInfo GetRelatedBundleAsPackage(string id, RelationType relationType, bool perMachine, Version version)
158 {
159 PackageInfo package = new PackageInfo();
160 package.Id = id;
161 package.Version = version.ToString();
162
163 switch (relationType)
164 {
165 case RelationType.Addon:
166 package.Type = PackageType.AddonBundle;
167 break;
168 case RelationType.Patch:
169 package.Type = PackageType.PatchBundle;
170 break;
171 case RelationType.Upgrade:
172 package.Type = PackageType.UpgradeBundle;
173 break;
174 default:
175 throw new Exception(string.Format("Unknown related bundle type: {0}", relationType));
176 }
177
178 return package;
179 }
180 }
181}
diff --git a/src/WixToolset.Mba.Core/SupportedFrameworkElement.cs b/src/WixToolset.Mba.Core/SupportedFrameworkElement.cs
new file mode 100644
index 00000000..37a31b69
--- /dev/null
+++ b/src/WixToolset.Mba.Core/SupportedFrameworkElement.cs
@@ -0,0 +1,47 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.Configuration;
7
8 /// <summary>
9 /// Handler for the supportedFramework configuration section.
10 /// </summary>
11 public sealed class SupportedFrameworkElement : ConfigurationElement
12 {
13 private static readonly ConfigurationProperty versionProperty = new ConfigurationProperty("version", typeof(string), null, ConfigurationPropertyOptions.IsRequired);
14 private static readonly ConfigurationProperty runtimeVersionProperty = new ConfigurationProperty("runtimeVersion", typeof(string));
15
16 /// <summary>
17 /// Creates a new instance of the <see cref="SupportedFrameworkElement"/> class.
18 /// </summary>
19 public SupportedFrameworkElement()
20 {
21 }
22
23 /// <summary>
24 /// Gets the version of the supported framework.
25 /// </summary>
26 /// <remarks>
27 /// The assembly specified by this name must contain a value matching the NETFX version registry key under
28 /// "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP".
29 /// </remarks>
30 [ConfigurationProperty("version", IsRequired = true)]
31 public string Version
32 {
33 get { return (string)base[versionProperty]; }
34 set { base[versionProperty] = value; }
35 }
36
37 /// <summary>
38 /// Gets the runtime version required by this supported framework.
39 /// </summary>
40 [ConfigurationProperty("runtimeVersion", IsRequired = false)]
41 public string RuntimeVersion
42 {
43 get { return (string)base[runtimeVersionProperty]; }
44 set { base[runtimeVersionProperty] = value; }
45 }
46 }
47}
diff --git a/src/WixToolset.Mba.Core/SupportedFrameworkElementCollection.cs b/src/WixToolset.Mba.Core/SupportedFrameworkElementCollection.cs
new file mode 100644
index 00000000..1a5aa2de
--- /dev/null
+++ b/src/WixToolset.Mba.Core/SupportedFrameworkElementCollection.cs
@@ -0,0 +1,36 @@
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
3namespace WixToolset.BootstrapperCore
4{
5 using System;
6 using System.Configuration;
7 using System.Diagnostics.CodeAnalysis;
8
9 /// <summary>
10 /// Handler for the supportedFramework collection.
11 /// </summary>
12 [SuppressMessage("Microsoft.Design", "CA1010:CollectionsShouldImplementGenericInterface")]
13 [ConfigurationCollection(typeof(SupportedFrameworkElement), AddItemName = "supportedFramework", CollectionType = ConfigurationElementCollectionType.BasicMap)]
14 public sealed class SupportedFrameworkElementCollection : ConfigurationElementCollection
15 {
16 public override ConfigurationElementCollectionType CollectionType
17 {
18 get { return ConfigurationElementCollectionType.BasicMap; }
19 }
20
21 protected override string ElementName
22 {
23 get { return "supportedFramework"; }
24 }
25
26 protected override ConfigurationElement CreateNewElement()
27 {
28 return new SupportedFrameworkElement();
29 }
30
31 protected override object GetElementKey(ConfigurationElement element)
32 {
33 return (element as SupportedFrameworkElement).Version;
34 }
35 }
36}
diff --git a/src/WixToolset.Mba.Core/WixToolset.BootstrapperCore.config b/src/WixToolset.Mba.Core/WixToolset.BootstrapperCore.config
new file mode 100644
index 00000000..1e284001
--- /dev/null
+++ b/src/WixToolset.Mba.Core/WixToolset.BootstrapperCore.config
@@ -0,0 +1,26 @@
1<?xml version="1.0" encoding="utf-8" ?>
2<!-- 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. -->
3
4
5<configuration>
6 <configSections>
7 <sectionGroup name="wix.bootstrapper" type="WixToolset.BootstrapperCore.BootstrapperSectionGroup, WixToolset.BootstrapperCore">
8 <section name="host" type="WixToolset.BootstrapperCore.HostSection, WixToolset.BootstrapperCore" />
9 </sectionGroup>
10 </configSections>
11 <startup useLegacyV2RuntimeActivationPolicy="true">
12 <supportedRuntime version="v4.0" />
13 <supportedRuntime version="v2.0.50727" />
14 </startup>
15 <wix.bootstrapper>
16 <!-- Example only. Use only if the startup/supportedRuntime above cannot discern supported frameworks. -->
17 <!--
18 <supportedFramework version="v4\Client" />
19 <supportedFramework version="v3.5" />
20 <supportedFramework version="v3.0" />
21 -->
22
23 <!-- Example only. Replace the host/@assemblyName attribute with assembly that implements BootstrapperApplication. -->
24 <host assemblyName="AssemblyWithClassThatInheritsFromBootstrapperApplication" />
25 </wix.bootstrapper>
26</configuration>
diff --git a/src/balutil/inc/IBootstrapperApplicationFactory.h b/src/balutil/inc/IBootstrapperApplicationFactory.h
new file mode 100644
index 00000000..e29c23bc
--- /dev/null
+++ b/src/balutil/inc/IBootstrapperApplicationFactory.h
@@ -0,0 +1,14 @@
1#pragma once
2// 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.
3
4
5#include "precomp.h"
6
7DECLARE_INTERFACE_IID_(IBootstrapperApplicationFactory, IUnknown, "2965A12F-AC7B-43A0-85DF-E4B2168478A4")
8{
9 STDMETHOD(Create)(
10 __in IBootstrapperEngine* pEngine,
11 __in const BOOTSTRAPPER_COMMAND *pCommand,
12 __out IBootstrapperApplication **ppApplication
13 );
14};