50% OFF!!!

Thursday, February 10, 2011

MSI | Embed images inside MSI installer file

In this post I show how to embed images inside MSI installer file.

The first try i made was to try adding splash image and banners to the installer through Visual-Studio User-Interface. (just added two jpg files into "Common Files Folder", and set the SplashBitmap and BannerBitmap attributes). But doing so, created a problem - when changing the image, new version installer did NOT changed the images (or the images disappeared).
So i needed another solution...

The next solution is just to INSERT those images (banner&splash) directly into the MSI file created by Visual-Studio.
I created file run.js file, which automaticlly runs when the build process finished, and edits the MSI. This is achieved by setting the PostBuildEvent on the Windows Installer project.

The event that added is to the PostBuildEvent: (remember to copy the file to the main folder of the Windows Installer project)
cscript.exe "$(ProjectDir)run.js" "$(BuiltOuputPath)"

In this way, you don't have to add any image file to your project, and it s embedded in the msi file (which u can edit any time).

The run.js file:
// run.js // Performs a post-build fixup of an msi

if (WScript.Arguments.Length != 1)
{
       WScript.StdErr.WriteLine(WScript.ScriptName + " file");
       WScript.Quit(1);
}

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

var sql
var view
var record

try {

    WScript.Echo("UPDATE default banner image");

    sql = "UPDATE `Binary` SET `Data` = ? WHERE `Name`= 'DefBannerBitmap'";
    view = database.OpenView(sql)
    record = installer.CreateRecord(1);
    record.SetStream(1, "C:\\installer_banner_img.jpg");
    view.Execute(record);
    view.Close();
       WScript.Echo("ADD splash image");
    sql = "INSERT INTO `Binary` (`Name`, `Data`) VALUES ('DefSplashBitmap', ?)";
    view = database.OpenView(sql)
    record = installer.CreateRecord(1);
    record.SetStream(1, "C:\\Installer_splash_img.jpg");
    view.Execute(record);
    view.Close();

    WScript.Echo("Update splash control");
    sql = "UPDATE `Control` SET `Text`='DefSplashBitmap' WHERE `Dialog_`='SplashForm' AND `Control`='SplashBmp'";
    view = database.OpenView(sql)
    view.Execute();
    view.Close();
       database.Commit();
}
catch (e) {
    WScript.StdErr.Write("|||ERROR||| ");
    WScript.StdErr.WriteLine(e.Message);
    WScript.Quit(1);
}

Note:
Before running this script, add a splash screen to the installer (using User-Interface view in Visual Studio)

(*) this is also a good example how to add/update binary(image) into your MSI using a sql script.

Best regard,
MDB-Blog

No comments:

Post a Comment