-
Notifications
You must be signed in to change notification settings - Fork 447
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optional Workload: Finalizer #10356
Optional Workload: Finalizer #10356
Conversation
ReleaseStr(sczProductId); | ||
ReleaseStr(sczProviderKey); | ||
ReleaseStr(sczDependentsKey); | ||
ReleaseRegKey(hkDependentsKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know regutil (and I can't find it around here), but I would assume that releasing something twice is not nice...
Also - we may call release with null... not sure if that works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
regutil is coming from the WiX SDK, defined as #define ReleaseRegKey(h) if (h) { ::RegCloseKey(h); h = NULL; }
strutil (also WiX SDK), is defined as #define ReleaseStr(pwz) if (pwz) { StrFree(pwz); }
, though it doesn't make the pointer NULL
.
I was concerned about too many open handles since we could be enumerating thousands of keys/subkeys, but if we hit an error we'd fall into the exit block with an unknown state of the various handles.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK - so it's macro magic... 😢 ... sometime I hate what people do with C++.
Anyway - in that case you're right - it will work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's been forever since I've done C++ and I'm not really familiar with the registry and MSI APIs, but generally looks good.
I've pushed some of the infrastructure changes needed to build the finalizer and add it to the SDK install bundle. |
Indeed it can, except that if it's managed code, we can't guarantee that .NET Framework is installed, and a self contained .NET Core application adds around 20-30MB to the installer size based on a number of early prototypes. This should not have too much maintenance and should be a one-off cost (which is also the reason for using the WiX SDK that has good wrappers for some of the registery functions) |
The finalizer is intended to be run only during uninstall of the standalone SDK. It's intended to remove any optional workload installations that have references to the SDK that's being removed. In short, it enumerates all the MSI dependency provider keys for the dependent value associated with the SDK.
If there are more than one dependent, it simply removes the SDK's reference. Otherwise, if the SDK is the only dependent, it removes the reference and then uninstalls the MSI, provided the MSI is still installed as sometimes, there can be corrupted/orphaned providers.
Below is an example of how the finalizer would be chained into the SDK bundle. The finalizer will only execute during uninstalls and because we don't actually install anything, the EXE's detection state is based on the fact that the bundle is being removed (
BOOTSTRAPPER_ACTION_UNINSTALL >= 3
). The install condition is set to true when the bundle is being installed, repaired or modified (BOOTSTRAPPER_ACTION_INSTALL >= 4
). If the InstallCondition is false at install time, the bundle will remove the EXE package (see this). TheSDK_DEP
property will be set based on the dependent value associated with the SDK.The finalizer is using the WiX SDK (dutil.lib). It is however not using deputil. While deputil does provide functionality around dependency providers, it is intended to handle a specific provider key whereas the finalizer needs to process all provider keys.