如何在程序 window 中卸载捆绑包的一部分而不删除它?

How to uninstall part of a bundle with out deleting it in the programs window?

我正在定制 Bootstrapper 以根据用户想要安装的内容安装多个 MSI。到目前为止一切正常,但我希望能够再次 运行 安装程序并选择要卸载的 MSI。如果要卸载所有已安装的 MSI,则删除捆绑包,否则保留它,以便用户可以添加或删除另一个 MSI。

我想在 PlanPackageBegin 事件处理程序中做这样的事情:

if (WisState == State.Uninstalling)
        {
            if (e.PackageId.Equals("MSI1", StringComparison.Ordinal))
            {
                if (requestMSI1 == RequestState.Present)
                {
                    e.State = RequestState.None;
                }
                else
                {
                    e.State = RequestState.Absent;
                }
            }
}

然后在 PlanComplete 事件处理程序中我开始:

Bootstrapper.Engine.Apply(System.IntPtr.Zero);

但是随后捆绑包也被卸载了。

如果不是所有 MSI 都将被卸载,我如何防止我的包被卸载?

我找到了解决问题的方法。

我没有计划卸载,而是计划进行修复以防止我的捆绑包被卸载。为了在卸载所有 MSI 时将其删除,我计划卸载。

if (requestMSI1 == RequestState.Absent && requestMSI2 == RequestState.Absent)
{
    this.WisState = State.FullUninstalling;
    Bootstrapper.Engine.Plan(LaunchAction.Uninstall);
}
else
{
    this.WisState = State.Uninstalling;
    Bootstrapper.Engine.Plan(LaunchAction.Repair);
}

然后我检查 PlanPackageBegin 如果我正在卸载(不是 FullUninstalling):

if (WisState == State.Uninstalling)
{
    if (e.PackageId.Equals("MSI1", StringComparison.Ordinal))
    {
        if (requestMSI1 == RequestState.Absent)
        {
            e.State = RequestState.Absent;
        }
        else
        {
            e.State = RequestState.None;
        }
    }
    else if (e.PackageId.Equals("MSI2", StringComparison.Ordinal))
    {
        if ("requestMSI" == RequestState.Absent)
        {
            e.State = RequestState.Absent;
        }
        else
        {
            e.State = RequestState.None;
        }
    }
}

如果我正在完全卸载,我会让 Bootstrapper 自行规划。

请注意,WisState 和 requestMSI1/2 是我更改的变量,具体取决于我的 UI 应该显示的内容和用户的选择。