安装前运行自定义操作

发布于 2024-10-12 07:28:46 字数 913 浏览 5 评论 0原文

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

这 3 个类执行以下操作:

  • 检查参数以允许使用许可信息进行无人值守安装(覆盖 Install 方法)
  • 删除以前安装的软件(使用 NSIS 安装程序安装,使用 Install 方法 ) >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");
    }
}

I have a basic setup project in Visual Studio 2010, and I am struggling with setting up custom actions. I have 3 Installer classes in a separate assembly.

The 3 classes do the following things:

  • Check for parameters to allow for unattended installation with licensing information (overrides the Install method)
  • Remove a previous installation of the software (installed with an NSIS installer, uses the BeforeInstall event)
  • Stop the program if it is running, using the BeforeInstall event

The problem is the last one, it seems the BeforeInstall event is never triggered. I've tried to make it create a file on disk, and displaying a MessageBox. It never triggers.

The "Primary output from SetupActions" has been added to the "Install" section in the Custom Actions editor. My Installer classes all have [RunInstaller(true)].

Code that does not work:

[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");
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

楠木可依 2024-10-19 07:28:46

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

据我所知,您想要实现的目标在 VS 2010 设置项目中是不可能的。也许,您应该使用 Wix(或 NSIS)!

Problem with this approach is that you want to run something before installation and that something resides in the dll/exe that gets onto the target machine only as a part of installation. So unless installation is done, you will not have your BeforeInstall code on the disk to run (and then you can make it run only as post install).

To my knowledge, what you want to achieve is not possible VS 2010 setup project. Perhaps, you should use Wix (or NSIS)!

请帮我爱他 2024-10-19 07:28:46

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

VinacC is correct above. To do this correctly, this needs to be done prior to File Costing. A bootstrapper would be a good place to do it. You want to get the machine cleaned of the old NSIS version before Windows Installer starts looking at what needs to be done to get to the latest version.

稳稳的幸福 2024-10-19 07:28:46

您不需要迁移到 WiX,但如果您在某种程度上使用 WiX,则可以这样做。

首先,您必须将 C# 代码传输到 WiX 自定义操作

然后,您将使用以下 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();
}

You don't need to migrate to WiX, but you can do it if you use WiX at some extent.

First you'll have to transfer you C# code to a WiX Custom Action.

Then you'll embed this Custom Action into the MSI using the following JScript code:

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文