@joebigelow / wix-1 / commits / 62352fab

Import files from BootstrapperCore repo.

Sean Hall committed Dec 11, 2019 at 19:34 UTC 62352fabd541aaa9d0a2c957c4bdd4b9c682df9c
26 files changed +5377
src/WixToolset.Mba.Core/BaseBootstrapperApplicationFactory.cs new
+16
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/BootstrapperApplication.cs new
+1591
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/BootstrapperApplicationData.cs new
+63
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/BootstrapperApplicationFactory.cs new
+86
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/BootstrapperApplicationFactoryAttribute.cs new
+35
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/BootstrapperCommand.cs new
+107
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/BootstrapperSectionGroup.cs new
+29
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/BundleInfo.cs new
+67
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/Engine.cs new
+516
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/EventArgs.cs new
+1903
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/Exceptions.cs new
+145
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/HostSection.cs new
+47
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/IBootstrapperApplicationData.cs new
+12
@@ -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 +
3 +namespace 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
src/WixToolset.Mba.Core/IBootstrapperApplicationFactory.cs new
+52
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/IBootstrapperCommand.cs new
+63
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/IBundleInfo.cs new
+16
@@ -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 +
3 +namespace 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
src/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs new
+65
@@ -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 +
3 +namespace 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
src/WixToolset.Mba.Core/IEngine.cs new
+176
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/IPackageInfo.cs new
+20
@@ -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 +
3 +namespace 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
src/WixToolset.Mba.Core/IVariables.cs new
+27
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/NativeMethods.cs new
+37
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/PackageInfo.cs new
+181
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/SupportedFrameworkElement.cs new
+47
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/SupportedFrameworkElementCollection.cs new
+36
@@ -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 +
3 +namespace 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 +}
src/WixToolset.Mba.Core/WixToolset.BootstrapperCore.config new
+26
@@ -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>
src/balutil/inc/IBootstrapperApplicationFactory.h new
+14
@@ -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 +
7 +DECLARE_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 +};