Pull to refresh

Advanced Installer + взаимодействие с внешней dll

Часто необходимо создать инсталяционный пакет который использует свой код при исполнении инсталятора. Можно конечно написать полность свой инсталятор, или выучить птичий язык инстолятора, а можно воспользоваться мощным инстолятором и подключить к нему свой код.

Задача:
В среде подготовки инсталляторов Advanced Installer разработать инсталлятор тестового приложения с добавлением пользовательской формы, реализовать взаимодействие формы с внешней dll.

Решение:
Создание проекта. Можно создать проект с помощь мастеров, например «Приложение Visual Studio». Мастер помогает заполнить большинство полей и импортировать даны для развёртывания. Однако, можно выбрать общий шаблон «Enterprise», и выполнить проектирование инсталлятора вручную.

image
Создание проекта. Имя ПО и название организации.

image
Выбираем тип распространения установочного пакета.

image
Указываем положение проекта инсталлятора и получаемого пакета.

Выбираем Solution с помощью диалога и импортируем его. При импорте Указываем конфигурацию. Release конечно же.
image

Указываем файлы. Указываем название ярлыка.

image
Указываем что делать с Redistributables.

После создания проекта, обязательно меняем его тип в опциях программы на Enterprise. Если не сменить тип, то не будет доступна работа с диалогами.
image

Подтверждаем свои намеренья. Обратной дороги назад уже не будет. Но нам и не нужно.

Вставим свой диалог после Welcome Dialog.

Я его назвал A_PLUS_B
image

На диалоге размещаем 3 элемента типа «Статический текст», вставляем в окне свойства «Обозначение».«Текст» Число А, Число Б, Сумма А и Б. Размещаем на диалоге 3 элемента типа «Поле ввода». Обратим внимание на их свойства. Нам нужно запомнить что их «имена свойства» равны EDIT_1_PROP, EDIT_2_PROP, EDIT_3_PROP. При желании можно поменять на что-то более вразумительное. Добавляем на диалог кнопку, меняем её текст на «=».
Далее нам необходимо создать DLL и подключить его к проекту.
В DLL мы создадим функцию сложения 2-х чисел A и В и сохранения результата значения в поле C.

Создание проекта в Microsoft Visual Studio. Проекты созданные авторами Advanced Installer сделаны MS Visual Studio 2003. Я вроде где-то встречал, что они её рекомендуют, но проект DLL созданной в MS Visual Studio 2008 тоже работает.

Создаём проект Visual C++ — Win 32 Project с помощью визарда MS Visual Studio 2008.
image

Выбираем тип проекта DLL
image

В созданном проекте например в файле a_plus_b.cpp создаём экспортируемую из DLL функцию.

Имя функции Sum. Ниже листинг.
#define DllExport __declspec( dllexport )
#define FIELD_LENGTH 20

//Sum function
DllExport UINT __stdcall Sum (MSIHANDLE hInstall)
{

TCHAR szPidKey[FIELD_LENGTH];
DWORD dwLen = sizeof(szPidKey) / sizeof(szPidKey[0]);

///retrieve the text entered by the user
UINT res = ::MsiGetProperty(hInstall, _T("EDIT_1_PROP"), szPidKey, &dwLen);
if(res != ERROR_SUCCESS)
{
//fail the installation
return 1;
}

int a = atoi((const char *)szPidKey);

TCHAR szPidKeyB[FIELD_LENGTH];
DWORD dwLenB = sizeof(szPidKeyB) / sizeof(szPidKeyB[0]);

///retrieve the text entered by the user
res = ::MsiGetProperty(hInstall, _T("EDIT_2_PROP"), szPidKeyB, &dwLenB);
if(res != ERROR_SUCCESS)
{
//fail the installation
return 1;
}

int b = atoi((const char *)szPidKeyB);

int c = a + b;

TCHAR szPidKeyC[FIELD_LENGTH];
itoa(c, (char*)szPidKeyC, 10);

//Write settings to property
res = ::MsiSetProperty(hInstall, _T("EDIT_3_PROP"), szPidKeyC);

if(res != ERROR_SUCCESS)
{
//fail the installation
return 1;
}

return 0;
}


Для получения данных из EditBox на диалоге инсталлятора воспользуемся функцией MsiGetProperty с указанием имени элемента на диалоге — EDIT_1_PROP, EDIT_2_PROP.
Возвращаемое значение вернём в элемент диалога EDIT_3_PROP при помощи вызова MsiSetProperty.

Добавляем в stdafx.h файл проекта:

#include <msi.h>
#include <msiquery.h>
#include <tchar.h>


Добавляем в свойствах проекта в Additional Dependences линкеру файл: msi.lib
image

Компилируем DLL. Для отладки можно пользоваться отладочной DLL

Далее производим подключение функции из созданного DLL к проекту инсталлятора.
image

Для этого в меню Настраиваемое поведение, в пункте «Настраиваемые действия», в дереве Install Sequences, добавим настраиваемое действие интерфейса. При этом укажем с помощью диалогов путь к DLL. Далее укажем имя функции. Наша функция ?Sum@@YGIK@Z – это её так c++ экспортирует. Можно использовать C нотацию экспорта, тогда имена будут более читабельные и не содержать параметров. Имя настраевомой функции A_PLUS_B.dll лучше поменять на что либо более удобоваримое, но в примере я этого не сделал для наглядности.

Следующее, что мы сделаем – добавим на кнопку «=» новое событие элемента управления. Для этого идём в меню «Пользовательский интерфейс» — «Диалоговые Окна» и там выбираем кнопку «=» на нашем диалоге.

Выбираем события публикации и говорим создать.

image

Выбираем DoAction и выбираем имя нашей функции A_PLUS_B.dll.
Говорим ОК.

Проект можно запустить, но он не вернет результат в C. Связанно это с тем, что Edit Control автоматически не рефрешится с помощью Windows Installer.

image

Поэтому добавляем ещё одно событие публикации на кнопку «=». Для этого выбираем события публикации и говорим создать.

image

В поле имя выбираем SetProperty, затем опять таки-же в имя вводим наш EDIT_3_PROP. В поле Аргумент тоже указываем EDIT_3_PROP.

Условие = 1. – Выполнять всегда.

Как результат имеем два события публикации

image

Запускаем наш проект инсталлятора. Вторым появляется наше окно. Вводим числа А и Б, нажимаем на кнопку =, в поле Сумма А и Б получаем результат.

image

Результат:
Advanced Installer + взаимодействие с внешней dll = Работает
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.