Tuesday, March 15, 2011

Чтение и изменение свойств инсталляционного пакета MSI

MSI пакет можно рассматривать как базу данных, которая хранит в себе информацию о том что куда и как устанавливать. Эту базу данных можно читать и редактировать на уже скомпилированном MSI пакете. Делать это можно при помощи утилиты orca.exe или программно.

Orca.exe - редактор таблиц для создания и редактирования пакетов Windows Installer и merge модулей.

Программно изменять таблицы можно при помощи специального COM-объекта. Ниже пример на JScript чтения из MSI-пакета наименования продукта:

read.js
function main() {
    var objArgs = WScript.Arguments;
    if (objArgs.length < 1) {
        WScript.Echo("invalid parameters for msi.js");
        WScript.Quit(1);
    }

    var msiPath = objArgs(0);
    // Return an error if the named MSI file doesn't exist.
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    if (!fso.FileExists(msiPath)) {
        WScript.Echo("File not found - " + msiPath);
        WScript.Quit(2);  // ERROR_FILE_NOT_FOUND
    }

    // Open the MSI database, or fail gracefully if an error occurs.
    try {
        var installer = new ActiveXObject("WindowsInstaller.Installer");
        var db = installer.OpenDatabase(msiPath, 0); // read-only
    } catch (e) {
        WScript.Echo("Error " + (e.number & 0xFFFF) + " opening msi file. " + e.message);
        WScript.Quit(e.number);
    }

    var view = db.OpenView("select Value from Property where Property = 'ProductName'");
    view.Execute();
    var ProductName = view.Fetch().StringData(1);
    view.Close();

    WScript.Echo(ProductName);
}

main();
Пример для изменения наименования продукта: write.js
function main() {
    var objArgs = WScript.Arguments;
    if (objArgs.length < 1) {
        WScript.Echo("invalid parameters for msi.js");
        WScript.Quit(1);
    }

    var msiPath = objArgs(0);
    // Return an error if the named MSI file doesn't exist.
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    if (!fso.FileExists(msiPath)) {
        WScript.Echo("File not found - " + msiPath);
        WScript.Quit(2);  // ERROR_FILE_NOT_FOUND
    }

    // Open the MSI database, or fail gracefully if an error occurs.
    try {
        var installer = new ActiveXObject("WindowsInstaller.Installer");
        var db = installer.OpenDatabase(msiPath, 1); // read-only
    } catch (e) {
        WScript.Echo("Error " + (e.number & 0xFFFF) + " opening msi file. " + e.message);
        WScript.Quit(e.number);
    }

    var view = db.OpenView("update Property set Value = 'New product name' where Property = 'ProductName'");
    view.Execute();
    view.Close();
    db.Commit();
}

main();
Ссылки по теме: Справка по объектам Windows Installer

No comments: