Ммногие знают об Inno Setup (open source система создания инсталляторов для Windows программ — wikipedia) но «стандартные» возможности её все же ограничены. Рассмотрим различные способы расширить эти «стандартные» возможности.
Довольно банально и просто — расширение возможностей Inno Setup заключается в подключении DLL. Так напишем эту DLL!
Так же потребуется def файл с следующим содержанием. Делается это для того что бы избежать декорирования процедур.
Компилируем следующей командой (из командной строки Visual Studio)
Теперь мы можем смело начинать писать скрипт в Inno Setup, я приведу лишь наиболее важные фрагменты.
stdcall — соглашение о вызове
files:test.dll — означает автоматически распаковать и использовать test.dll из секции [Files]
run_test — имя процедуры в DLL
Все просто и легко, пока нам не потребуется вызывать процедуру из DLL в скрипте Inno Setup. Звучит страшно но я поясню наглядным примером.
И так что бы реализовать это нам потребуется вспомнить asm плюс не забывать что в борландской stdcall регистры ecx edx поменяны местами. Плюс я добавил в комментариях дополнительные возможности.
Перепишем скрипт.
Так же DLL'ками к Inno Setup можно прикрутить почти любой OLE контейнер, различные нововведения в Windows 7, отрисовку различной графики посредством GDI+ и многое другое. Плюс ко всему Inno Setup довольно часто обновляется что не может не радовать, в отличии от почившего NSIS. Возможно когда я всё таки поставлю Delphi то перепишу и на неё.
Исходный код + скомпилированная DLL
Довольно банально и просто — расширение возможностей Inno Setup заключается в подключении DLL. Так напишем эту DLL!
#include <windows.h>
extern "C" void __stdcall run_test(char *s)
{
MessageBox(NULL, s, "Caption", MB_OK);
}
Так же потребуется def файл с следующим содержанием. Делается это для того что бы избежать декорирования процедур.
EXPORTS
run_test
Компилируем следующей командой (из командной строки Visual Studio)
cl -O2 -LD test.cpp test.def User32.lib
Теперь мы можем смело начинать писать скрипт в Inno Setup, я приведу лишь наиболее важные фрагменты.
[Files]
Source: test.dll; Flags: dontcopy
[Code]
procedure RunTest(s: PAnsiChar); external 'run_test@files:test.dll stdcall'; // описание
//...
function //...
begin
RunTest('Test message!');
WizardForm.Close;
end;
//...
stdcall — соглашение о вызове
files:test.dll — означает автоматически распаковать и использовать test.dll из секции [Files]
run_test — имя процедуры в DLL
Все просто и легко, пока нам не потребуется вызывать процедуру из DLL в скрипте Inno Setup. Звучит страшно но я поясню наглядным примером.
procedure TestCallback(s: PAnsiChar);
begin
MsgBox(s, mbInformation, MB_OK);
end;
function //...
begin
RunTest(@TestCallback);
end;
И так что бы реализовать это нам потребуется вспомнить asm плюс не забывать что в борландской stdcall регистры ecx edx поменяны местами. Плюс я добавил в комментариях дополнительные возможности.
extern "C" void __stdcall run_test(void(*func)(char *s), int unk)
{
char *text = "Test message!";
__asm
{
mov eax, unk
mov edx, text
// mov ecx, param2 для второго параметра
call func
// mov eax, result узнаем что вернула процедура из в скрипте
}
}
Перепишем скрипт.
type
TTestCallbackProc=procedure(s: PAnsiChar);
procedure RunTest(p: TTestCallbackProc); external 'run_test@files:test.dll stdcall';
procedure TestCallback(s: PAnsiChar);
begin
MsgBox(s, mbInformation, MB_OK);
end;
function //...
begin
RunTest(@TestCallback);
WizardForm.Close;
end;
Так же DLL'ками к Inno Setup можно прикрутить почти любой OLE контейнер, различные нововведения в Windows 7, отрисовку различной графики посредством GDI+ и многое другое. Плюс ко всему Inno Setup довольно часто обновляется что не может не радовать, в отличии от почившего NSIS. Возможно когда я всё таки поставлю Delphi то перепишу и на неё.
Исходный код + скомпилированная DLL