【问题标题】:MSI installer cancel not workingMSI 安装程序取消不起作用
【发布时间】:2026-01-06 18:00:02
【问题描述】:

我有一个 MSI 安装程序(设置项目),它实际上通过 system.diagnostic.process 调用 Windows 窗体 exe。

这个表单实际上是从用户那里获取输入来在 sql server 中恢复一个 .bak 文件。

但如果发生任何异常,我无法取消设置。即使点击安装程序的取消按钮,安装回滚也不会开始。

请建议如何处理。

【问题讨论】:

  • 您需要通过自定义操作来实现任何额外的操作,而不仅仅是任何旧的 EXE。它们包括用于安装、回滚、卸载等的挂钩,您可以将这些挂钩与您的流程集成。

标签: c# deployment windows-installer


【解决方案1】:

创建调用您的 windows 窗体 exe 的新项目并向其添加安装程序类,或者只是将安装程序类添加到您的 windows 窗体 exe(您必须更改它的输出类型并对其进行一些修改,例如,没有 Main() 方法,或者没有设置启动对象,并且您的表单是从安装操作内部调用的)

安装程序类应如下所示:

[RunInstaller(true)]
public  partial class Installer1 : System.Configuration.Install.Installer
{
    public Installer1()
    {
        InitializeComponent();
    }
    [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
    public override void Install(IDictionary stateSaver)
    {
        base.Install(stateSaver);
        // Do your magic here, call your form, do your thing...

    }
 [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
    public override void Commit(IDictionary savedState)
    {

        base.Commit(savedState);
    }

    [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
    public override void Rollback(IDictionary savedState)
    {
        // if something goes wrong, it's here you correct it and rollback the system to its previous state and undo what you already changed
        base.Rollback(savedState);
    }

    [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
    public override void Uninstall(IDictionary savedState)
    {
        // Here you undo changes when you cancel
        base.Uninstall(savedState);
    }

}

当您准备好安装程序项目后,转到安装项目自定义操作并将安装程序项目的主要输出添加到其安装、提交、回滚和卸载“文件夹”。

另一件有用的事情是获取应用程序的安装目录并将其路径传递给安装程序类。您将自定义操作的 CustomActionData 属性设置为

/INSTALLDIR="[TARGETDIR]\"

在您的安装程序类中,您可以使用以下方式获取目录:

Context.Parameters["INSTALLDIR"]

编辑:如果从 Install 方法中抛出异常,安装将被取消。据我所知,这是在中间“取消”安装的唯一方法。你必须创建一个异常并抛出它。例如像这样:

If (SomethingWentWrong) throw new Exception("My exception description")

当然,如果异常是由其他东西引发的(我的意思是,不是你自愿“创建”的),回滚也应该开始。但如果您进行一些自定义更改,则必须从自定义操作的安装程序的 install 方法中抛出。

对不起,如果我有点太详细了,但我已经解决了自己的一系列麻烦,所以如果我能帮助某人避免它,我会很高兴:)

【讨论】: