@joebigelow / wix-1 / commits / 780cd25e

WIXFEAT:6164 Add OnPlanMsiPackage.

Sean Hall committed May 15, 2020 at 13:48 UTC 780cd25e41f2d2982807a0a2a24a734684d27fe6
9 files changed +274 -4
src/WixToolset.Mba.Core/BootstrapperApplication.cs
+32 -2
@@ -161,6 +161,11 @@ namespace WixToolset.Mba.Core
161 /// </summary>
162 public event EventHandler<PlanMsiFeatureEventArgs> PlanMsiFeature;
163
164 + /// <summary>
165 + /// Fired when the engine is planning an MSI or MSP package.
166 + /// </summary>
167 + public event EventHandler<PlanMsiPackageEventArgs> PlanMsiPackage;
168 +
169 /// <summary>
170 /// Fired when the engine has completed planning the installation of a specific package.
171 /// </summary>
@@ -658,6 +663,19 @@ namespace WixToolset.Mba.Core
663 }
664 }
665
666 + /// <summary>
667 + /// Called when the engine is planning an MSI or MSP package.
668 + /// </summary>
669 + /// <param name="args">Additional arguments for this event.</param>
670 + protected virtual void OnPlanMsiPackage(PlanMsiPackageEventArgs args)
671 + {
672 + EventHandler<PlanMsiPackageEventArgs> handler = this.PlanMsiPackage;
673 + if (null != handler)
674 + {
675 + handler(this, args);
676 + }
677 + }
678 +
679 /// <summary>
680 /// Called when then engine has completed planning the installation of a specific package.
681 /// </summary>
@@ -1288,6 +1306,18 @@ namespace WixToolset.Mba.Core
1306 return args.HResult;
1307 }
1308
1309 + int IBootstrapperApplication.OnPlanMsiPackage(string wzPackageId, bool fExecute, ActionState action, ref bool fCancel, ref BURN_MSI_PROPERTY actionMsiProperty, ref INSTALLUILEVEL uiLevel, ref bool fDisableExternalUiHandler)
1310 + {
1311 + PlanMsiPackageEventArgs args = new PlanMsiPackageEventArgs(wzPackageId, fExecute, action, fCancel, actionMsiProperty, uiLevel, fDisableExternalUiHandler);
1312 + this.OnPlanMsiPackage(args);
1313 +
1314 + fCancel = args.Cancel;
1315 + actionMsiProperty = args.ActionMsiProperty;
1316 + uiLevel = args.UiLevel;
1317 + fDisableExternalUiHandler = args.DisableExternalUiHandler;
1318 + return args.HResult;
1319 + }
1320 +
1321 int IBootstrapperApplication.OnPlanPackageComplete(string wzPackageId, int hrStatus, PackageState state, RequestState requested, ActionState execute, ActionState rollback)
1322 {
1323 var args = new PlanPackageCompleteEventArgs(wzPackageId, hrStatus, state, requested, execute, rollback);
@@ -1466,9 +1496,9 @@ namespace WixToolset.Mba.Core
1496 return args.HResult;
1497 }
1498
1469 - int IBootstrapperApplication.OnExecutePackageBegin(string wzPackageId, bool fExecute, ActionState action, ref bool fCancel)
1499 + int IBootstrapperApplication.OnExecutePackageBegin(string wzPackageId, bool fExecute, ActionState action, INSTALLUILEVEL uiLevel, bool fDisableExternalUiHandler, ref bool fCancel)
1500 {
1471 - ExecutePackageBeginEventArgs args = new ExecutePackageBeginEventArgs(wzPackageId, fExecute, action, fCancel);
1501 + ExecutePackageBeginEventArgs args = new ExecutePackageBeginEventArgs(wzPackageId, fExecute, action, uiLevel, fDisableExternalUiHandler, fCancel);
1502 this.OnExecutePackageBegin(args);
1503
1504 fCancel = args.Cancel;
src/WixToolset.Mba.Core/EventArgs.cs
+73 -1
@@ -995,6 +995,64 @@ namespace WixToolset.Mba.Core
995 public FeatureState State { get; set; }
996 }
997
998 + /// <summary>
999 + /// Additional arguments used when the engine is planning an MSI or MSP package.
1000 + /// </summary>
1001 + [Serializable]
1002 + public class PlanMsiPackageEventArgs : CancellableHResultEventArgs
1003 + {
1004 + /// <summary>
1005 + /// Creates a new instance of the <see cref="PlanMsiPackageEventArgs"/> class.
1006 + /// </summary>
1007 + /// <param name="packageId">The identity of the package planned for.</param>
1008 + /// <param name="shouldExecute">Whether the package is planned to execute or roll back.</param>
1009 + /// <param name="action">The action planned for the package.</param>
1010 + /// <param name="cancelRecommendation">The recommendation from the engine.</param>
1011 + /// <param name="actionMsiProperty">The requested MSI property to add.</param>
1012 + /// <param name="uiLevel">The requested internal UI level.</param>
1013 + /// <param name="disableExternalUiHandler">Whether Burn is requested to set up an external UI handler.</param>
1014 + public PlanMsiPackageEventArgs(string packageId, bool shouldExecute, ActionState action, bool cancelRecommendation, BURN_MSI_PROPERTY actionMsiProperty, INSTALLUILEVEL uiLevel, bool disableExternalUiHandler)
1015 + : base(cancelRecommendation)
1016 + {
1017 + this.PackageId = packageId;
1018 + this.ShouldExecute = shouldExecute;
1019 + this.Action = action;
1020 + this.ActionMsiProperty = actionMsiProperty;
1021 + this.UiLevel = uiLevel;
1022 + this.DisableExternalUiHandler = disableExternalUiHandler;
1023 + }
1024 +
1025 + /// <summary>
1026 + /// Gets identity of the package planned for.
1027 + /// </summary>
1028 + public string PackageId { get; private set; }
1029 +
1030 + /// <summary>
1031 + /// Gets whether the package is planned to execute or roll back.
1032 + /// </summary>
1033 + public bool ShouldExecute { get; private set; }
1034 +
1035 + /// <summary>
1036 + /// Gets the action planned for the package.
1037 + /// </summary>
1038 + public ActionState Action { get; private set; }
1039 +
1040 + /// <summary>
1041 + /// Gets or sets the requested MSI property to add.
1042 + /// </summary>
1043 + public BURN_MSI_PROPERTY ActionMsiProperty { get; set; }
1044 +
1045 + /// <summary>
1046 + /// Gets or sets the requested internal UI level.
1047 + /// </summary>
1048 + public INSTALLUILEVEL UiLevel { get; set; }
1049 +
1050 + /// <summary>
1051 + /// Gets or sets whether Burn is requested to set up an external UI handler.
1052 + /// </summary>
1053 + public bool DisableExternalUiHandler { get; set; }
1054 + }
1055 +
1056 /// <summary>
1057 /// Additional arguments used when then engine has completed planning the installation of a specific package.
1058 /// </summary>
@@ -1503,13 +1561,17 @@ namespace WixToolset.Mba.Core
1561 /// <param name="packageId">The identity of the package to act on.</param>
1562 /// <param name="shouldExecute">Whether the package is being executed or rolled back.</param>
1563 /// <param name="action">The action about to be executed.</param>
1564 + /// <param name="uiLevel">The internal UI level (if this is an MSI or MSP package).</param>
1565 + /// <param name="disableExternalUiHandler">Whether Burn will set up an external UI handler (if this is an MSI or MSP package).</param>
1566 /// <param name="cancelRecommendation">The recommendation from the engine.</param>
1507 - public ExecutePackageBeginEventArgs(string packageId, bool shouldExecute, ActionState action, bool cancelRecommendation)
1567 + public ExecutePackageBeginEventArgs(string packageId, bool shouldExecute, ActionState action, INSTALLUILEVEL uiLevel, bool disableExternalUiHandler, bool cancelRecommendation)
1568 : base(cancelRecommendation)
1569 {
1570 this.PackageId = packageId;
1571 this.ShouldExecute = shouldExecute;
1572 this.Action = action;
1573 + this.UiLevel = uiLevel;
1574 + this.DisableExternalUiHandler = disableExternalUiHandler;
1575 }
1576
1577 /// <summary>
@@ -1526,6 +1588,16 @@ namespace WixToolset.Mba.Core
1588 /// Gets the action about to be executed.
1589 /// </summary>
1590 public ActionState Action { get; private set; }
1591 +
1592 + /// <summary>
1593 + /// Gets the internal UI level (if this is an MSI or MSP package).
1594 + /// </summary>
1595 + public INSTALLUILEVEL UiLevel { get; private set; }
1596 +
1597 + /// <summary>
1598 + /// Gets whether Burn will set up an external UI handler (if this is an MSI or MSP package).
1599 + /// </summary>
1600 + public bool DisableExternalUiHandler { get; private set; }
1601 }
1602
1603 /// <summary>
src/WixToolset.Mba.Core/IBootstrapperApplication.cs
+109
@@ -219,6 +219,18 @@ namespace WixToolset.Mba.Core
219 [MarshalAs(UnmanagedType.Bool)] ref bool fCancel
220 );
221
222 + [PreserveSig]
223 + [return: MarshalAs(UnmanagedType.I4)]
224 + int OnPlanMsiPackage(
225 + [MarshalAs(UnmanagedType.LPWStr)] string wzPackageId,
226 + [MarshalAs(UnmanagedType.Bool)] bool fExecute,
227 + [MarshalAs(UnmanagedType.U4)] ActionState action,
228 + [MarshalAs(UnmanagedType.Bool)] ref bool fCancel,
229 + [MarshalAs(UnmanagedType.U4)] ref BURN_MSI_PROPERTY actionMsiProperty,
230 + [MarshalAs(UnmanagedType.U4)] ref INSTALLUILEVEL uiLevel,
231 + [MarshalAs(UnmanagedType.Bool)] ref bool fDisableExternalUiHandler
232 + );
233 +
234 [PreserveSig]
235 [return: MarshalAs(UnmanagedType.I4)]
236 int OnPlanPackageComplete(
@@ -393,6 +405,8 @@ namespace WixToolset.Mba.Core
405 [MarshalAs(UnmanagedType.LPWStr)] string wzPackageId,
406 [MarshalAs(UnmanagedType.Bool)] bool fExecute,
407 [MarshalAs(UnmanagedType.U4)] ActionState action,
408 + [MarshalAs(UnmanagedType.U4)] INSTALLUILEVEL uiLevel,
409 + [MarshalAs(UnmanagedType.Bool)] bool fDisableExternalUiHandler,
410 [MarshalAs(UnmanagedType.Bool)] ref bool fCancel
411 );
412
@@ -832,4 +846,99 @@ namespace WixToolset.Mba.Core
846 Restart,
847 ReloadBootstrapper,
848 }
849 +
850 + /// <summary>
851 + /// The property Burn will add so the MSI can know the planned action for the package.
852 + /// </summary>
853 + public enum BURN_MSI_PROPERTY
854 + {
855 + /// <summary>
856 + /// No property will be added.
857 + /// </summary>
858 + None,
859 +
860 + /// <summary>
861 + /// Add BURNMSIINSTALL=1
862 + /// </summary>
863 + Install,
864 +
865 + /// <summary>
866 + /// Add BURNMSIMODFIY=1
867 + /// </summary>
868 + Modify,
869 +
870 + /// <summary>
871 + /// Add BURNMSIREPAIR=1
872 + /// </summary>
873 + Repair,
874 +
875 + /// <summary>
876 + /// Add BURNMSIUNINSTALL=1
877 + /// </summary>
878 + Uninstall,
879 + }
880 +
881 + /// <summary>
882 + /// From msi.h
883 + /// https://docs.microsoft.com/en-us/windows/win32/api/msi/nf-msi-msisetinternalui
884 + /// </summary>
885 + [Flags]
886 + public enum INSTALLUILEVEL
887 + {
888 + /// <summary>
889 + /// UI level is unchanged
890 + /// </summary>
891 + NoChange = 0,
892 +
893 + /// <summary>
894 + /// default UI is used
895 + /// </summary>
896 + Default = 1,
897 +
898 + /// <summary>
899 + /// completely silent installation
900 + /// </summary>
901 + None = 2,
902 +
903 + /// <summary>
904 + /// simple progress and error handling
905 + /// </summary>
906 + Basic = 3,
907 +
908 + /// <summary>
909 + /// authored UI, wizard dialogs suppressed
910 + /// </summary>
911 + Reduced = 4,
912 +
913 + /// <summary>
914 + /// authored UI with wizards, progress, errors
915 + /// </summary>
916 + Full = 5,
917 +
918 + /// <summary>
919 + /// display success/failure dialog at end of install
920 + /// </summary>
921 + EndDialog = 0x80,
922 +
923 + /// <summary>
924 + /// display only progress dialog
925 + /// </summary>
926 + ProgressOnly = 0x40,
927 +
928 + /// <summary>
929 + /// do not display the cancel button in basic UI
930 + /// </summary>
931 + HideCancel = 0x20,
932 +
933 + /// <summary>
934 + /// force display of source resolution even if quiet
935 + /// </summary>
936 + SourceResOnly = 0x100,
937 +
938 + /// <summary>
939 + /// show UAC prompt even if quiet
940 + /// Can only be used if on Windows Installer 5.0 or later
941 + /// </summary>
942 + UacOnly = 0x200,
943 + }
944 }
src/balutil/inc/BAFunctions.h
+1
@@ -64,6 +64,7 @@ enum BA_FUNCTIONS_MESSAGE
64 BA_FUNCTIONS_MESSAGE_ONAPPLYCOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYCOMPLETE,
65 BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN,
66 BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE,
67 + BA_FUNCTIONS_MESSAGE_ONPLANMSIPACKAGE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIPACKAGE,
68
69 BA_FUNCTIONS_MESSAGE_ONTHEMELOADED = 1024,
70 BA_FUNCTIONS_MESSAGE_WNDPROC,
src/balutil/inc/BalBaseBAFunctions.h
+15
@@ -298,6 +298,19 @@ public: // IBootstrapperApplication
298 return S_OK;
299 }
300
301 + virtual STDMETHODIMP OnPlanMsiPackage(
302 + __in_z LPCWSTR /*wzPackageId*/,
303 + __in BOOL /*fExecute*/,
304 + __in BOOTSTRAPPER_ACTION_STATE /*action*/,
305 + __inout BOOL* /*pfCancel*/,
306 + __inout BURN_MSI_PROPERTY* /*pActionMsiProperty*/,
307 + __inout INSTALLUILEVEL* /*pUiLevel*/,
308 + __inout BOOL* /*pfDisableExternalUiHandler*/
309 + )
310 + {
311 + return S_OK;
312 + }
313 +
314 virtual STDMETHODIMP OnPlanPackageComplete(
315 __in_z LPCWSTR /*wzPackageId*/,
316 __in HRESULT /*hrStatus*/,
@@ -490,6 +503,8 @@ public: // IBootstrapperApplication
503 __in_z LPCWSTR /*wzPackageId*/,
504 __in BOOL /*fExecute*/,
505 __in BOOTSTRAPPER_ACTION_STATE /*action*/,
506 + __in INSTALLUILEVEL /*uiLevel*/,
507 + __in BOOL /*fDisableExternalUiHandler*/,
508 __inout BOOL* /*pfCancel*/
509 )
510 {
src/balutil/inc/BalBaseBAFunctionsProc.h
+1
@@ -99,6 +99,7 @@ static HRESULT WINAPI BalBaseBAFunctionsProc(
99 case BA_FUNCTIONS_MESSAGE_ONAPPLYCOMPLETE:
100 case BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN:
101 case BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE:
102 + case BA_FUNCTIONS_MESSAGE_ONPLANMSIPACKAGE:
103 hr = BalBaseBootstrapperApplicationProc((BOOTSTRAPPER_APPLICATION_MESSAGE)message, pvArgs, pvResults, pvContext);
104 break;
105 case BA_FUNCTIONS_MESSAGE_ONTHEMELOADED:
src/balutil/inc/BalBaseBootstrapperApplication.h
+16
@@ -311,6 +311,20 @@ public: // IBootstrapperApplication
311 return S_OK;
312 }
313
314 + virtual STDMETHODIMP OnPlanMsiPackage(
315 + __in_z LPCWSTR /*wzPackageId*/,
316 + __in BOOL /*fExecute*/,
317 + __in BOOTSTRAPPER_ACTION_STATE /*action*/,
318 + __inout BOOL* pfCancel,
319 + __inout BURN_MSI_PROPERTY* /*pActionMsiProperty*/,
320 + __inout INSTALLUILEVEL* /*pUiLevel*/,
321 + __inout BOOL* /*pfDisableExternalUiHandler*/
322 + )
323 + {
324 + *pfCancel |= CheckCanceled();
325 + return S_OK;
326 + }
327 +
328 virtual STDMETHODIMP OnPlanPackageComplete(
329 __in_z LPCWSTR /*wzPackageId*/,
330 __in HRESULT /*hrStatus*/,
@@ -604,6 +618,8 @@ public: // IBootstrapperApplication
618 __in_z LPCWSTR wzPackageId,
619 __in BOOL fExecute,
620 __in BOOTSTRAPPER_ACTION_STATE /*action*/,
621 + __in INSTALLUILEVEL /*uiLevel*/,
622 + __in BOOL /*fDisableExternalUiHandler*/,
623 __inout BOOL* pfCancel
624 )
625 {
src/balutil/inc/BalBaseBootstrapperApplicationProc.h
+13 -1
@@ -402,7 +402,7 @@ static HRESULT BalBaseBAProcOnExecutePackageBegin(
402 __inout BA_ONEXECUTEPACKAGEBEGIN_RESULTS* pResults
403 )
404 {
405 - return pBA->OnExecutePackageBegin(pArgs->wzPackageId, pArgs->fExecute, pArgs->action, &pResults->fCancel);
405 + return pBA->OnExecutePackageBegin(pArgs->wzPackageId, pArgs->fExecute, pArgs->action, pArgs->uiLevel, pArgs->fDisableExternalUiHandler, &pResults->fCancel);
406 }
407
408 static HRESULT BalBaseBAProcOnExecutePatchTarget(
@@ -504,6 +504,15 @@ static HRESULT BalBaseBAProcOnLaunchApprovedExeComplete(
504 return pBA->OnLaunchApprovedExeComplete(pArgs->hrStatus, pArgs->dwProcessId);
505 }
506
507 +static HRESULT BalBaseBAProcOnPlanMsiPackage(
508 + __in IBootstrapperApplication* pBA,
509 + __in BA_ONPLANMSIPACKAGE_ARGS* pArgs,
510 + __inout BA_ONPLANMSIPACKAGE_RESULTS* pResults
511 + )
512 +{
513 + return pBA->OnPlanMsiPackage(pArgs->wzPackageId, pArgs->fExecute, pArgs->action, &pResults->fCancel, &pResults->actionMsiProperty, &pResults->uiLevel, &pResults->fDisableExternalUiHandler);
514 +}
515 +
516 /*******************************************************************
517 BalBaseBootstrapperApplicationProc - requires pvContext to be of type IBootstrapperApplication.
518 Provides a default mapping between the new message based BA interface and
@@ -689,6 +698,9 @@ static HRESULT WINAPI BalBaseBootstrapperApplicationProc(
698 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE:
699 hr = BalBaseBAProcOnLaunchApprovedExeComplete(pBA, reinterpret_cast<BA_ONLAUNCHAPPROVEDEXECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONLAUNCHAPPROVEDEXECOMPLETE_RESULTS*>(pvResults));
700 break;
701 + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIPACKAGE:
702 + hr = BalBaseBAProcOnPlanMsiPackage(pBA, reinterpret_cast<BA_ONPLANMSIPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANMSIPACKAGE_RESULTS*>(pvResults));
703 + break;
704 }
705 }
706
src/balutil/inc/IBootstrapperApplication.h
+14
@@ -194,6 +194,18 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A
194 __inout BOOL* pfCancel
195 ) = 0;
196
197 + // OnPlanMsiPackage - called when the engine plans an MSI or MSP package.
198 + //
199 + STDMETHOD(OnPlanMsiPackage)(
200 + __in_z LPCWSTR wzPackageId,
201 + __in BOOL fExecute, // false means rollback.
202 + __in BOOTSTRAPPER_ACTION_STATE action,
203 + __inout BOOL* pfCancel,
204 + __inout BURN_MSI_PROPERTY* pActionMsiProperty,
205 + __inout INSTALLUILEVEL* pUiLevel,
206 + __inout BOOL* pfDisableExternalUiHandler
207 + ) = 0;
208 +
209 // OnPlanPackageComplete - called after the engine plans a package.
210 //
211 STDMETHOD(OnPlanPackageComplete)(
@@ -390,6 +402,8 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A
402 __in_z LPCWSTR wzPackageId,
403 __in BOOL fExecute, // false means rollback.
404 __in BOOTSTRAPPER_ACTION_STATE action,
405 + __in INSTALLUILEVEL uiLevel,
406 + __in BOOL fDisableExternalUiHandler,
407 __inout BOOL* pfCancel
408 ) = 0;
409