I'm using a custom bootstrapper application with a bundle that installs 2 packages: PackageA and PackageB. They are part of the same product but don't both need to be there: the user can install either or both, and they can be upgraded independently.
Suppose the user has installed both packages. I create major upgrades for both packages and publish a new bundle. The user chooses to upgrade PackageA but not PackageB. When this happens, the new bundle calls the old bundle at the end of installation, as an embedded uninstall. The old bundle then wants to uninstall PackageB. I can suppress this by handling PlanPackageBegin and setting the RequestState to None. That works fine to prevent it from removing PackageB, and the old version of the bootstrapper unregisters itself from ARP, which is what I want.
Now what happens if the user wants to uninstall PackageB? ARP launches the new version of the bootstrapper, which detects PackageB as a related package, but I don't see a way to tell it to uninstall a related package.
Do I need to code this myself to call MSI directly to remove the package? Or just leave the individual package visible in ARP rather than registering the bundle?
You shouldn't allow partial upgrades. Bundles weren't designed for that. If the user installs the new bundle and wants to keep PackageB then the new version should be installed, otherwise if they don't want PackageB then it should be uninstalled. When bundles share the same upgrade code, then newer versions are supposed to completely replace the older one.
Also, keep in mind that by default the bundle is caching the package. So if the bundle that owns that package is removed without removing the cached package, then nothing will ever remove that cache.