назад к списку статей

Построение x64 проекта установки в 32-разрядной среде для x64 сервера

Построение x64 проекта установки в 32-разрядной средеЕсли в 64-разрядный проект установки добавляется настраиваемое действие, при построении Visual Studio встраивает в установщик MSI 32-разрядную библиотеку InstallUtilLib.dll в качестве программы InstallUtil. В свою очередь, для запуска 64-разрядного настраиваемого действия загружается 32-разрядная платформа .NET Framework, что приводит к возникновению исключения BadImageFormatException.

При попытке поставить такой установщик на 64-разрядный сервер, возникнет исключение, произойдет откат установки, и вы увидите вот такое сообщение:

Построение x64 проекта установки в 32-разрядной среде

Исправить подобное поведение можно путем замены 32-разрядной версии библиотеки InstallUtilLib.dll ее 64-разрядным эквивалентом.

Итак, у нас есть установщик SetupMySuperProgramm_x64.msi, скомпилированный в 32-разрядной среде под 64-разрядную платформу, который мы хотим установить на 64-разрядной машине.

Варианта решения проблемы два:

1. Замена InstallUtilLib.dll с помощью утилиты Orca

Orca.msi входит в состав утилит Microsoft Windows SDK for Windows, которые можно загрузить с официального сайта Microsoft. Установите Orca.msi на 64-разрядном сервере. В контекстном меню файлов .msi появится пункт «Edit With Orca».

В редакторе Orca откройте SetupMySuperProgramm_x64.msi и выполните следующие действия:

  • в левом столбце выберите пункт Binary:

    Построение x64 проекта установки в 32-разрядной среде

  • на правой панели выберите пункт InstallUtil и откройте [Binary Data], дважды щелкнув по ней;
  • установите флажок напротив действия "Read binary from filename", и нажмите кнопку "Browse":

    Построение x64 проекта установки в 32-разрядной среде

  • выберите файл C:\Windows\Microsoft.NET\Framework64\Версия Framework\InstallUtilLib.dll.
    Примечание 1: Версия Framework выбирается та, под которую был написан установщик SetupMySuperProgramm_x64.msi.
    Примечание 2: Каталог Framework64 есть только на 64-разрядных машинах. Он соответствует 64-разрядному типу процессора.
  • нажмите кнопку "ОК". Сохраните изменения в файле.

2. Автоматическая замена InstallUtilLib.dll

Постоянно пользоваться утилитой Orca быстро надоеcт, поэтому логичным шагом будет автоматизировать данный процесс:

  • создайте в Visual Studio консольное приложение CreateX64Setup;
  • добавьте в проект Com-сборку «Microsoft Windows Installer Object Library». Бывают случаи некорректного добавления этой библиотеки. Тогда просто добавьте в проект ссылку на библиотеку C:\Windows\system32\msi.dll;
  • скопируйте в папку с нашим проектом (в каталог Debug, где будет выходной exe-шник проекта) библиотеку
    C:\Windows\Microsoft.NET\Framework64\Версия Framework\InstallUtilLib.dll
    с 64-разрядного сервера, на котором будете ставить свой установщик;
  • скопируйте в тот же каталог испытуемый установщик SetupMySuperProgramm_x64.msi;
  • вставьте в приложение код:

using System;
using System.IO;
using WindowsInstaller;
 
//добавить в проект сборку C:\WINDOWS\system32\msi.dll
namespace CreateX64Setup
{
  class Program
  {
    static void Main(string[] args)
    {
       string util64 = "InstallUtilLib.dll";
       string setupFile = "SetupMySuperProgramm_x64.msi";
       if (!File.Exists(util64)) return;
       if (!File.Exists(setupFile)) return;
 
       Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer");
       Object installerObject = Activator.CreateInstance(type);
       Installer installer = (Installer)installerObject;
 
       Database db = installer.OpenDatabase(setupFile,
           MsiOpenDatabaseMode.msiOpenDatabaseModeTransact);
 
       View view = db.OpenView(@"SELECT `Name`,`Data` FROM 
          `Binary` where `Binary`.`Name` = 'InstallUtil'");
       view.Execute(null);
       Record record = view.Fetch();
       if (record != null)
       {
          record.SetStream(2, util64);
          view.Modify(MsiViewModify.msiViewModifyUpdate, record);
          db.Commit();
       }
       view.Close();
    }
  }
}

Наша утилита заменит в исходном установщике родную библиотеку InstallUtilLib.dll на 64-разрядную.

назад к списку статей


I'mon Google+ .