Как сделать инсталлятор ZDLL модуля на InnoSetup для MiniM Database Server
Для того чтобы сделать инсталлятор, надо определить его цели. В нашем случае это будут:
Секция [Setup] заполняется учетной информацией общего плана.
В секции [CustomMessages] прописываем константные строки:
Итого, из ключевых нестандартных элементов мы использовали:
Для того чтобы сделать инсталлятор, надо определить его цели. В нашем случае это будут:
- Предложить выбрать один из имеющихся установленный на компьютере серверов MiniM.
- Если этот сервер не запущен, то запустить его.
- Выложить в его подкаталог /bin файл zdll модуля и рутину поддержки, если она есть.
- Выполнить импорт рутины на сервер.
Секция [Setup] заполняется учетной информацией общего плана.
[Setup]
AppName=MiniM ZDLL module for NTLM autorization
AppVerName=MiniM ZDLL NTLM module
OutputBaseFilename=setup-zntlm
DefaultDirName={pf}\MiniM
DefaultGroupName=MiniM
AppPublisher=Eugene Karataev
AppPublisherURL=http://karataev.nm.ru
AllowNoIcons=yes
OutputDir=W:\MiniM\zdll\install
Compression=lzma
SolidCompression=yes
Uninstallable = no
В секции [Files] указываем два устанавливаемых файла:
[Files]
Source: "w:\MiniM\bin\zntlm.dll"; DestDir: "{app}\bin"
Source: "w:\MiniM\zdll\zntlm\%ntlm.rou"; DestDir: "{app}\bin"
Далее, нам надо не использовать предлагаемый по умолчанию инсталлятором выбор
каталога, а запросить пользователя выбрать один из имеющихся установленных на
компьютере серверов MiniM. Перечень установленных серверов можем получить из
реестра, а вместо страницы выбора каталога нам нужно сделать свою страницу для
очередного шага инсталлятора.
В секции [CustomMessages] прописываем константные строки:
[CustomMessages] SelectInstanceCaption=Select available MiniM instance to install to SelectInstanceDescription=В секции [Code] описываем функцию создания свой страницы для шага инсталлятора и в функцию InitializeWizard добавляем ее вызов:
[Code]
var
lblInstance: TLabel;
lbInstanceList: TListBox;
InstallName: String;
procedure SelectInstance_Activate(Page: TWizardPage);
begin
lbInstanceList.ItemIndex := -1;
WizardForm.NextButton.Enabled := False;
end;
function SelectInstance_ShouldSkipPage(Page: TWizardPage): Boolean;
begin
Result := False;
end;
function SelectInstance_BackButtonClick(Page: TWizardPage): Boolean;
begin
Result := True;
end;
function SelectInstance_NextButtonClick(Page: TWizardPage): Boolean;
begin
Result := True;
end;
procedure SelectInstance_CancelButtonClick(Page: TWizardPage; var Cancel,
Confirm: Boolean);
begin
end;
procedure SelectInstance_Click( Sender: TObject);
var
Index: Integer;
Dir: String;
Group: String;
begin
Index := lbInstanceList.ItemIndex;
if Index = - 1 then
begin
WizardForm.NextButton.Enabled := False;
end
else
begin
InstallName := lbInstanceList.Items.Strings[ Index];
InstallName := Copy( InstallName, 1, Pos( ' ', InstallName) - 1);
RegQueryStringValue( HKEY_LOCAL_MACHINE,
'SOFTWARE\MiniM Group\MiniM\Instance\' +
InstallName, 'Directory', Dir);
WizardForm.DirBrowseButton.Visible := False;
WizardForm.DirEdit.Enabled := False;
WizardForm.DirEdit.Text := Dir;
RegQueryStringValue( HKEY_LOCAL_MACHINE,
'SOFTWARE\MiniM Group\MiniM\Instance\' +
InstallName, 'Group', Group);
WizardForm.GroupEdit.Text := Group;
WizardForm.NextButton.Enabled := True;
end;
end;
function SelectInstance_CreatePage(PreviousPageId: Integer): Integer;
var
Page: TWizardPage;
Names: TArrayOfString;
I: Integer;
Ver: String;
begin
Page := CreateCustomPage(
PreviousPageId,
ExpandConstant('{cm:SelectInstanceCaption}'),
ExpandConstant('{cm:SelectInstanceDescription}')
);
{ lblInstance }
lblInstance := TLabel.Create(Page);
with lblInstance do
begin
Parent := Page.Surface;
Left := ScaleX(16);
Top := ScaleY(8);
Width := ScaleX(150);
Height := ScaleY(13);
Caption := 'Select available MiniM instance:';
end;
{ lbInstanceList }
lbInstanceList := TListBox.Create(Page);
with lbInstanceList do
begin
Parent := Page.Surface;
Left := ScaleX(24);
Top := ScaleY(24);
Width := ScaleX(321);
Height := ScaleY(201);
TabOrder := 0;
OnClick := @SelectInstance_Click;
end;
// заполняем список перечнем имеющихся инсталляций
RegGetSubkeyNames( HKEY_LOCAL_MACHINE,
'SOFTWARE\MiniM Group\MiniM\Instance', Names);
for I := 0 to GetArrayLength(Names)-1 do
begin
RegQueryStringValue( HKEY_LOCAL_MACHINE,
'SOFTWARE\MiniM Group\MiniM\Instance\' +
Names[ I], 'Version', Ver);
lbInstanceList.Items.Add( Names[ I] +
' (ver. ' + Ver + ')');
end;
lbInstanceList.ItemIndex := -1;
with Page do
begin
OnActivate := @SelectInstance_Activate;
OnShouldSkipPage := @SelectInstance_ShouldSkipPage;
OnBackButtonClick := @SelectInstance_BackButtonClick;
OnNextButtonClick := @SelectInstance_NextButtonClick;
OnCancelButtonClick := @SelectInstance_CancelButtonClick;
end;
Result := Page.ID;
end;
procedure InitializeWizard();
begin
SelectInstance_CreatePage(wpWelcome);
end;
Для того, чтобы инсталлятор не смог продолжить работу пока не выбран сервер
MiniM, укажем это в функции SelectInstance_Activate
procedure SelectInstance_Activate(Page: TWizardPage); begin lbInstanceList.ItemIndex := -1; WizardForm.NextButton.Enabled := False; end;И в функции-обработчике выбора в списке SelectInstance_Click укажем разрешение продолжить работу:
if Index = - 1 then
begin
WizardForm.NextButton.Enabled := False;
end
else
begin
...
WizardForm.NextButton.Enabled := True;
end;
Шаги изменения состояния DirBrowseButton и DirEdit используем, чтобы указать
инсталлятору что каталог инсталляции мы выбрали самостоятельно:
WizardForm.DirBrowseButton.Visible := False;
WizardForm.DirEdit.Enabled := False;
WizardForm.DirEdit.Text := Dir;
После того, как файл dll и rou установлены инсталлятором в нужный каталог (а это
выбранный нами программно каталог, соответствующий переменной {app} и его
подкаталог /bin), надо запустить сервер. Если он уже запущен, то игнорировать
результат. Это выполняется в функции CurStepChanged на шаге CurStep =
ssPostInstall.
procedure CurStepChanged(CurStep: TSetupStep);
var
AppDir: String;
ErrorCode: Integer;
begin
if CurStep = ssPostInstall then
begin
AppDir := ExpandConstant('{app}');
// start mnmsvc.exe
ShellExec( 'open', 'net',
'start "MiniM Service for ' + InstallName, AppDir + '\bin',
SW_HIDE, ewWaitUntilTerminated, ErrorCode);
// import routines
ShellExec( 'open', AppDir +
'\bin\minim.exe',
'-x "zn \"%sys"" d imp^boot0(\"%ntlm.rou\")" -h',
AppDir + '\bin',
SW_SHOW, ewWaitUntilTerminated, ErrorCode);
end;
end;
В результате компиляции получаем exe с инсталлятором, который при запуске
выводит приветственное информационное сообщение о том, что он устанавливает,
предлагает выбрать один из имеющихся серверов MiniM, установленных на
компьютере, устанавливает в подкаталог /bin два файла - dll + rou и проводит
импорт рутины в нужную область. По окончании работы инсталлятора ZDLL модуль
готов к работе.
Итого, из ключевых нестандартных элементов мы использовали:
- Создали свою дополнительную страницу в шаги визарда
- Отменили использование штатной страницы выбора каталога
- Вставили в пост-инсталл шаг запуск сервера через вызов net start
- Вставили в пост-инсталл шаг импорт рутины в том же виде, в котором он используется собственно инсталлятором сервера.
Комментариев нет:
Отправить комментарий