|
85 | 85 | ================================================================ |
86 | 86 | Custom Actions |
87 | 87 |
|
88 | | - All three CAs are immediate (run in msiexec's own context, which is |
89 | | - elevated/SYSTEM under SCCM) so we avoid the CustomActionData dance |
90 | | - that deferred CAs require. ExeCommand interpolates [PROPERTY] tokens |
91 | | - at sequence time. Return="check" makes a non-zero exit roll back |
92 | | - the install transaction. |
| 88 | + All four CAs run DEFERRED with Impersonate=no — they execute |
| 89 | + during the install script phase (after InstallFiles physically |
| 90 | + writes the .exe to disk) in SYSTEM context. Immediate CAs were |
| 91 | + tried first but failed with MSI error 1721 ("program required |
| 92 | + could not be run") because immediate CAs run during sequence |
| 93 | + *building*, before the binary is on disk. |
| 94 | +
|
| 95 | + Deferred CAs can't read MSI properties directly. The standard |
| 96 | + workaround is paired SetProperty elements that populate the |
| 97 | + CustomActionData property which the deferred CA then reads as |
| 98 | + its command line. |
93 | 99 | ================================================================ |
94 | 100 | --> |
95 | 101 |
|
96 | | - <!-- Configure with inline credentials: runs when APIKEY is set and |
97 | | - BOOTSTRAPFILE is not. Tenant config (customer ID, endpoint, key, |
98 | | - frequency) comes from msiexec command line. --> |
| 102 | + <!-- Deferred command-runners. ExeCommand="[CustomActionData]" pulls |
| 103 | + the actual command line from the CustomActionData property, |
| 104 | + which the SetProperty elements below populate at sequence |
| 105 | + time (when [INSTALLFOLDER], [CUSTOMERID], etc. ARE expandable). --> |
| 106 | + |
99 | 107 | <CustomAction Id="RunConfigureInline" |
100 | 108 | Directory="INSTALLFOLDER" |
101 | | - ExeCommand='"[INSTALLFOLDER]stepsecurity-dev-machine-guard.exe" configure --non-interactive --customer-id "[CUSTOMERID]" --api-endpoint "[APIENDPOINT]" --api-key "[APIKEY]" --scan-frequency "[SCANFREQUENCY]"' |
102 | | - Execute="immediate" |
| 109 | + ExeCommand="[CustomActionData]" |
| 110 | + Execute="deferred" |
| 111 | + Impersonate="no" |
103 | 112 | Return="check"/> |
104 | 113 |
|
105 | | - <!-- Configure from a pre-staged JSON: runs when BOOTSTRAPFILE is set. |
106 | | - Recommended for SCCM since the API key never appears on the |
107 | | - msiexec command line (and therefore never in AppEnforce.log). --> |
108 | 114 | <CustomAction Id="RunConfigureFromFile" |
109 | 115 | Directory="INSTALLFOLDER" |
110 | | - ExeCommand='"[INSTALLFOLDER]stepsecurity-dev-machine-guard.exe" configure --non-interactive --from-file "[BOOTSTRAPFILE]"' |
111 | | - Execute="immediate" |
| 116 | + ExeCommand="[CustomActionData]" |
| 117 | + Execute="deferred" |
| 118 | + Impersonate="no" |
112 | 119 | Return="check"/> |
113 | 120 |
|
114 | | - <!-- Register the Windows Task Scheduler entry via the binary's own |
115 | | - `install` subcommand. Internally that shells out to schtasks.exe; |
116 | | - no PowerShell, no .NET, no WMI. --> |
117 | 121 | <CustomAction Id="RunInstallScheduledTask" |
118 | 122 | Directory="INSTALLFOLDER" |
119 | | - ExeCommand='"[INSTALLFOLDER]stepsecurity-dev-machine-guard.exe" install' |
120 | | - Execute="immediate" |
| 123 | + ExeCommand="[CustomActionData]" |
| 124 | + Execute="deferred" |
| 125 | + Impersonate="no" |
121 | 126 | Return="check"/> |
122 | 127 |
|
123 | | - <!-- Uninstall path: remove the scheduled task before MSI removes the |
124 | | - .exe. Return="ignore" so a missing task (already removed manually) |
125 | | - doesn't block uninstall. --> |
126 | 128 | <CustomAction Id="RunUninstallScheduledTask" |
127 | 129 | Directory="INSTALLFOLDER" |
128 | | - ExeCommand='"[INSTALLFOLDER]stepsecurity-dev-machine-guard.exe" uninstall' |
129 | | - Execute="immediate" |
| 130 | + ExeCommand="[CustomActionData]" |
| 131 | + Execute="deferred" |
| 132 | + Impersonate="no" |
130 | 133 | Return="ignore"/> |
131 | 134 |
|
| 135 | + <!-- SetProperty elements: WiX shorthand for an immediate Type 51 CA. |
| 136 | + Each one sets a property whose name matches a deferred CA Id; |
| 137 | + MSI auto-populates that CA's CustomActionData from this value |
| 138 | + at execution time. Property tokens like [INSTALLFOLDER] and |
| 139 | + [APIKEY] expand here (in the immediate phase) — so by the time |
| 140 | + the deferred CA runs, the command line is fully resolved. --> |
| 141 | + |
| 142 | + <SetProperty Id="RunConfigureInline" |
| 143 | + Value='"[INSTALLFOLDER]stepsecurity-dev-machine-guard.exe" configure --non-interactive --customer-id "[CUSTOMERID]" --api-endpoint "[APIENDPOINT]" --api-key "[APIKEY]" --scan-frequency "[SCANFREQUENCY]"' |
| 144 | + Sequence="execute" |
| 145 | + Before="RunConfigureInline" |
| 146 | + Condition="APIKEY AND NOT BOOTSTRAPFILE AND NOT Installed"/> |
| 147 | + |
| 148 | + <SetProperty Id="RunConfigureFromFile" |
| 149 | + Value='"[INSTALLFOLDER]stepsecurity-dev-machine-guard.exe" configure --non-interactive --from-file "[BOOTSTRAPFILE]"' |
| 150 | + Sequence="execute" |
| 151 | + Before="RunConfigureFromFile" |
| 152 | + Condition="BOOTSTRAPFILE AND NOT Installed"/> |
| 153 | + |
| 154 | + <SetProperty Id="RunInstallScheduledTask" |
| 155 | + Value='"[INSTALLFOLDER]stepsecurity-dev-machine-guard.exe" install' |
| 156 | + Sequence="execute" |
| 157 | + Before="RunInstallScheduledTask" |
| 158 | + Condition="NOT Installed"/> |
| 159 | + |
| 160 | + <SetProperty Id="RunUninstallScheduledTask" |
| 161 | + Value='"[INSTALLFOLDER]stepsecurity-dev-machine-guard.exe" uninstall' |
| 162 | + Sequence="execute" |
| 163 | + Before="RunUninstallScheduledTask" |
| 164 | + Condition="REMOVE="ALL""/> |
| 165 | + |
132 | 166 | <!-- |
133 | 167 | InstallExecuteSequence: where each CA fires in the MSI sequence. |
134 | 168 |
|
|
0 commit comments