安装前运行自定义操作

时间:2011-01-14 10:11:59

标签: c# windows-installer custom-action

我在Visual Studio 2010中有一个基本的安装项目,我正在努力设置自定义操作。我在一个单独的程序集中有3个安装程序类。

这3节课做了以下事情:

  • 检查参数以允许使用许可信息进行无人参与安装(覆盖Install方法)
  • 删除以前安装的软件(随NSIS安装程序一起安装,使用BeforeInstall事件)
  • 使用BeforeInstall事件
  • 停止程序运行

问题是最后一个问题,似乎永远不会触发BeforeInstall事件。我试图让它在磁盘上创建一个文件,并显示MessageBox。它永远不会触发。

“SetupActions的主要输出”已添加到“自定义操作”编辑器的“安装”部分。我的安装程序类都有[RunInstaller(true)]

不起作用的代码:

[RunInstaller(true)]
public partial class InstallerStopProgram : System.Configuration.Install.Installer
{
    public InstallerStopProgram()
    {
        InitializeComponent();
    }

    private void InstallerStopProgram_BeforeInstall(object sender, InstallEventArgs e)
    {
        MessageBox.Show("This is never displayed during the install");
    }
}

3 个答案:

答案 0 :(得分:2)

这种方法的问题是您希望在安装之前运行某些内容并且某些内容驻留在dll / exe中,该dll / exe只作为一部分进入目标计算机安装。因此,除非安装完成,否则您不会在磁盘上运行BeforeInstall代码(然后您可以使其仅在安装后运行)。

据我所知,你想要实现的是VS 2010安装项目。也许,你应该使用Wix(或NSIS)!

答案 1 :(得分:0)

VinacC在上面是正确的。要正确执行此操作,需要在文件成本核算之前完成此操作。引导程序是一个很好的地方。在Windows Installer开始查看需要执行哪些操作以获取最新版本之前,您希望清除旧NSIS版本的计算机。

答案 2 :(得分:0)

您无需迁移到WiX,但如果您在某种程度上使用WiX,则可以执行此操作。

首先,您必须将C#代码转移到WiX Custom Action

然后,您将使用以下JScript代码将此自定义操作嵌入到MSI中:

var installer = WScript.CreateObject("WindowsInstaller.Installer");
var filespec = WScript.Arguments(0);
var msiOpenDatabaseModeTransact = 1;
var msiViewModifyAssign         = 3;
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);

var sqlQuery = "SELECT `Name`,`Data` FROM Binary";
var view = database.OpenView(sqlQuery);
var record = installer.CreateRecord(2);
record.StringData(1) = "myAction";
view.Execute(record);
var binaryPath = WScript.ScriptFullName.replace(WScript.ScriptName, "SetupAction.CA.dll");
record.SetStream(2, binaryPath);
view.Modify(msiViewModifyAssign, record);
Execute("INSERT INTO `CustomAction` (`Action`, `Type`, `Source`, `Target`)  VALUES ('myActionId', 1, 'myAction', 'MySimpleAction')");
Execute("INSERT INTO `InstallUISequence` (`Action`, `Sequence`)  VALUES ('myActionId', 26)");
database.Commit();

function Execute(sql) {
    view = database.OpenView(sql);
    view.Execute();
    view.Close();
}