Running custom action before installation
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 "In开发者_开发百科stall" 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");
}
}
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)!
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.
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();
}
精彩评论