1. Уважаемые гости и пользователи форума.
    Администрация настоятельно рекомендует не регистрировать несколько аккаунтов для одного пользователя. При выявлении наличия мультиаккаунтов будут заблокированы все учетные записи данного пользователя.
    Аккаунты, зарегистрированные на временную почту будут также заблокированы.

FAQ FAQ по Inno Setup

Тема в разделе "Inno Setup", создана пользователем Shegorat, 16 июн 2011.

Метки:
  1. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    Эта тема предназначена как сборник скриптов и примеров.
    Правила в этой теме следующие:
    1. Один пост - один пример.
    2. Все посты оформляются в виде вопрос - ответ.
    3. Для большего удобства новые посты оформляются также как уже существующие. Ниже пример формления
    4. Если к вашему примеру прилагаются файлы, заливайте их во вложение.

    [B][COLOR=DarkRed]В:[/COLOR][/B] Как написать простейший инсталлятор?
    [B][COLOR=DarkBlue]О:[/COLOR][/B] Примерно так
    [SPOILER=Код][CODE]
    [Setup]
    AppName=My Program
    AppVersion=1.5
    DefaultDirName={pf}\My Program
    DefaultGroupName=My Program
    UninstallDisplayIcon={app}\MyProg.exe
    Compression=lzma2
    SolidCompression=yes
    OutputDir=userdocs:Inno Setup Examples Output

    [Files]
    Source: "MyProg.exe"; DestDir: "{app}"
    Source: "MyProg.chm"; DestDir: "{app}"
    Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme

    [Icons]
    Name: "{group}\My Program"; Filename: "{app}\MyProg.exe"
    [/CODE][/SPOILER]
     
    YURSHAT, aibek1996, Хамик и ещё 1-му нравится это.
  2. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Как узнать где находится Setup.exe на CD или на жестком диске?
    О: Примерно так
    Код (Text):
    [Setup]
    AppName=MyApp
    AppVerName=MyApp
    DefaultDirName={pf}\MyApp

    [code]
    type
      SECURITY_ATTRIBUTES = record
        nLength: DWord;
        lpSecurityDescriptor: longint;
        bInheritHandle: Boolean;
      end;

    const
      GENERIC_READ = $80000000;
      GENERIC_WRITE = $40000000;
      CREATE_ALWAYS = 2;

    function CreateFile(lpFileName: PChar; dwDesiredAccess, dwShareMode: DWord; LPSECURITY_ATTRIBUTES: SECURITY_ATTRIBUTES; dwCreationDisposition, dwFlagsAndAttributes: DWord; hTemplateFile: THandle): THandle; external 'CreateFileA@kernel32.dll stdcall';
    function CloseHandle(Handle: THandle): Boolean; external 'CloseHandle@kernel32.dll stdcall';

    function ISEnvHDD(): Boolean;
    var Hndl: Thandle; SA: SECURITY_ATTRIBUTES;
    begin
      Result:= False;
      SA.nLength:=SizeOf(SA);
      SA.bInheritHandle:=True;
      Hndl:= CreateFile(PChar(ExpandConstant('{src}\test.tmp')), GENERIC_READ or GENERIC_WRITE, 0, SA, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
      if Hndl>0 then Result:= True else Result:=False;
      CloseHandle(Hndl);
      DeleteFile(ExpandConstant('{src}\test.tmp'));
    end;

    function InitializeSetup(): Boolean;
    begin
    Result:= True;
    if ISEnvHDD then begin
      MsgBox('Setup.exe Находится на HDD. Запуск невозможен', mbConfirmation, MB_OK);
      Result:=False;
    end;
    end;
     
    DICI BF, Craj и LexBell нравится это.
  3. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Как сделать проверку через реестр установлена программа или нет?
    О: Так
    Код (Text):
    [Setup]
    AppName=MyApp
    AppverName=MyApp
    DefaultDirName={pf}\MyApp

    [Registry]
    Root: HKLM; Subkey: SOFTWARE\MyApp; ValueName: InstallPath; ValueType: string; ValueData: {app}; Flags: uninsdeletekey

    [code]
    function InitializeSetup(): Boolean;
    begin
      Result:= True;
      if RegValueExists(HKLM, 'SOFTWARE\MyApp', 'InstallPath') then begin
        MsgBox('Копия данной программы уже установлена! Установка будет прекращена', mbConfirmation, MB_OK);
        Result:= False;
      end;
    end;
     
    Nemko, DICI BF, Хамик и ещё 1-му нравится это.
  4. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Как добавить описание к компонентам в ComponentsList?
    О: Вот пример без использования различных библиотек (Требуется расширенная версия InnoSetup от ResTools)
    Код (Text):
    [Setup]
    AppName=My Program
    AppVerName=My Program 1.5
    DefaultDirName={pf}\My Program
    DefaultGroupName=My Program
    ComponentsListTVStyle=true

    [Languages]
    Name: russian; MessagesFile: compiler:Languages\Russian.isl

    [CustomMessages]
    russian.ComponentsName1=Моя программа™
    russian.ComponentsName2=Помощь
    russian.ComponentsName2_1=Документация
    russian.ComponentsName2_2=Руководство пользователя
    russian.ComponentsInfoPanel1=Описание
    russian.ComponentsInfoPanel2=Наведите курсор мыши на компонент, чтобы прочитать его описание.
    russian.ComponentsDescription1=Устанавливается обязательно
    russian.ComponentsDescription2=Помощь
    russian.ComponentsDescription3=Прочитать документацию
    russian.ComponentsDescription4=Прочитать руководство пользователя

    [Components]
    Name: readme; Description: Справка; Types: full custom;
    Name: readme\en; Description: "Английская "; Types: full custom; Flags: fixed
    Name: readme\ru; Description: Русская; Types: full

    ;*************************************************************************
    Name: plugs; Description: Плагины; Types: full ; Flags: collapsed
    Name: plugs\wlx; Description: Внутреннего просмотра; Types: full
    Name: plugs\wcx; Description: Архиваторные; Types: full
    Name: plugs\wfx; Description: Системные; Types: full
    Name: plugs\wfx\CanonCam; Description: CanonCam; Types: full
    Name: plugs\wfx\PluginManager; Description: PluginManager; Types: full
    Name: plugs\wfx\Registry; Description: Registry; Types: full
    Name: plugs\wfx\Services; Description: Services; Types: full
    Name: plugs\wfx\StartupGuard; Description: StartupGuard; Types: full
    Name: plugs\wdx; Description: Другие; Types: full

    [Code]
    type
      TComponentDesc = record Description: String; Index: Integer; end;

    var
      Descs: array of TComponentDesc;
      Info: TNewStaticText;
      InfoCaption: TNewStaticText;
      InfoPanel: TPanel;
      Indx: Integer;

    procedure ShowDescription(Sender: TObject; X, Y, Index: Integer; Area: TItemArea);
    var i: Integer;
    begin
      Indx:=-1;
      for i:= 0 to GetArrayLength(Descs)-1 do begin
      if (Descs[i].Index=Index) then begin Indx:=i; Break end; end;
      if (Indx >=0)and(Area=iaItem) then Info.Caption:= Descs[Indx].Description else Info.Caption:= ExpandConstant('{cm:ComponentsInfoPanel2}');
    end;

    procedure AddDescription(AIndex: Integer; ADescription: String);
    var i, k: Integer;
    begin
    i:= GetArrayLength(Descs); SetArrayLength(Descs, i+1);
    Descs[i].Description:= ADescription; Descs[i].Index:= AIndex-1
    end;

    procedure InitializeWizard();
    begin
      WizardForm.TypesCombo.Visible:=False;
      WizardForm.ComponentsList.Height := ScaleY(181) - WizardForm.TypesCombo.Top;
      WizardForm.ComponentsList.Top := WizardForm.TypesCombo.Top;
      WizardForm.ComponentsList.Width := ScaleX(417);
      WizardForm.ComponentsList.OnItemMouseMove:= @ShowDescription

      InfoPanel := TPanel.Create(WizardForm);
      InfoPanel.Parent := WizardForm.SelectComponentsPage;
      InfoPanel.Caption := '';
      InfoPanel.Top := ScaleY(190);
      InfoPanel.Left := ScaleX(0);
      InfoPanel.Width := ScaleX(417);
      InfoPanel.Height := ScaleY(40);
      InfoPanel.BevelInner := bvRaised;
      InfoPanel.BevelOuter := bvLowered;
      InfoCaption := TNewStaticText.Create(WizardForm);
      InfoCaption.Parent := WizardForm.SelectComponentsPage;
      InfoCaption.Caption := ExpandConstant('{cm:ComponentsInfoPanel1}');
      InfoCaption.Left := ScaleX(7);
      InfoCaption.Top := InfoPanel.Top - ScaleY(6);
      InfoCaption.Font.Color := clActiveCaption;

      Info := TNewStaticText.Create(WizardForm);
      Info.Parent := InfoPanel;
      Info.AutoSize := False;
      Info.Left := ScaleX(6);
      Info.Width := ScaleX(403);
      Info.Top := ScaleY(12);
      Info.Height := ScaleY(24);
      Info.Caption := ExpandConstant('{cm:ComponentsInfoPanel2}');
      Info.WordWrap := true;

      AddDescription(1, 'Справка'); //первый параметр - это номер компонента, идет последовательно от начала записи компонентов
      AddDescription(2, 'Английская справка'); //Второй параметр - это собственно описание компонента
      AddDescription(3, 'Русская справка');
      AddDescription(4, 'Плагины');
      AddDescription(5, 'Внутреннего просмотра');
      AddDescription(6, 'Архиваторные');
      AddDescription(7, 'Системные');
      AddDescription(8, 'CanonCam');
      AddDescription(9, 'PluginManager');
      AddDescription(10, 'Registry');
      AddDescription(11, 'Services');
      AddDescription(12, 'StartupGuard');
      AddDescription(13, 'Другие');

    end;
     
    Grizla и Craj нравится это.
  5. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Как внести значение в INI-файл в зависимости от выбранного чекбокса
    О: Так
    Код (Text):
    [Setup]
    AppName=My Program
    AppVerName=My Program 1.5
    AppPublisher=My Company, Inc.
    DefaultDirName={pf}\My Program
    DefaultGroupName=My Program
    OutputBaseFilename=setup
    Compression=lzma
    SolidCompression=yes

    [Languages]
    Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"

    [Run]
    Filename: "{app}\MyProg"; Description: "{cm:LaunchProgram, MyProg}"; Flags: nowait postinstall skipifsilent

    [Code]
    var
    IniCheckBox: TCheckBox;

    procedure InitializeWizard();
    begin
      IniCheckBox:= TCheckBox.Create(WizardForm);
      IniCheckBox.Left:= WizardForm.RunList.Left + 4;
      IniCheckBox.Top:= WizardForm.RunList.Top + 10;
      IniCheckBox.Width:= WizardForm.RunList.Width;
      IniCheckBox.Height:= 14
      IniCheckBox.Caption:=' Изменить язык интерфейса на русский';
      IniCheckBox.Parent:= WizardForm.FinishedPage;
    end;

    procedure DeinitializeSetup();
    begin
      if WizardForm.CurPageID = WpFinished then
      begin
        if IniCheckBox.Checked then
          SetIniString('Setting','Language', 'RU',ExpandConstant('{app}\Language.ini'))     //Секция, подключ, значение, файл Ini
        else
          SetIniString('Setting','Language', 'EN',ExpandConstant('{app}\Language.ini'))
      end;
    end;
     
    Infest и Craj нравится это.
  6. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Как удалить кнопки свернуть, развернуть из окна инсталлятора?
    О: Так
    Код (Text):
    [Setup]
    AppName=MyApp
    AppVerName=MyApp
    DefaultDirname={pf}\MyApp

    [code]
    const
      GWL_STYLE = -16;

      WS_MINIMIZEBOX = $20000;
      WS_MAXIMIZEBOX = $10000;
     
    function SetWindowLong(Wnd: HWnd; Index: Integer; NewLong: Longint): Longint; external 'SetWindowLongA@user32.dll stdcall';
    function GetWindowLong(hWnd: HWND; nIndex: Integer): Longint; external 'GetWindowLongA@user32.dll stdcall';

    procedure initializeWizard();
    begin
      SetWindowLong(WizardForm.handle, GWL_STYLE, GetWindowLong(WizardForm.handle, GWL_STYLE)and(not WS_MINIMIZEBOX)and(not WS_MAXIMIZEBOX));
    end;
     
    Craj, Shift85, ReFLeXx и ещё 1-му нравится это.
  7. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Как динамически создать батник?
    О: Примерно так
    Код (Text):
    [Setup]
    AppName=MyApp
    AppVername=MyApp
    DefaultDirName={pf}\MyApp
    DisableWelcomePage=True

    [code]
    procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
    begin
      Confirm:= False;
      Cancel:= True;
    end;

    function InitializeSetup(): Boolean;
    var List: TStringList; src, dest, bat: string; res: Integer;
    begin
      src:= ExpandConstant('{src}');
      BrowseForFolder('Choose destination dir', dest, True);
      bat:= ExpandConstant('{userappdata}\exec.bat');
      List:= TStringList.Create;
      List.Add('echo off');
      List.Add('set src='+src);
      List.Add('set dest='+dest);
      List.Add('@echo SourceDir: "%src%"');
      List.Add('@echo DestinationDir: "%dest%"');
      List.Add('pause');
      List.Add('del "'+bat+'"');
      List.Add('pause');
      List.SaveToFile(bat);
      List.Free;
      Exec(bat, '', '', SW_SHOW, ewNoWait, Res);
    end;
     
    Loner, Craj и ReFLeXx нравится это.
  8. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Как добавить проверку свободного/необходимого места на жестком диске?
    О: Так
    Код (Text):
    #define NeedSize 4380
    #define NeedInstallSize 7890

    [Setup]
    AppName=MyApp
    AppVerName=MyApp
    DefaultDirname={pf}\MyApp

    [code]
    var
      TotalSpaceLabel, FreeSpaceLabel, NeedSpacelabel, InstallSpaceLabel: TLabel;
      FreeMB, TotalMB: Cardinal;

    function NumToStr(Float: Extended): String;
    begin
      Result:= format('%.2n', [Float]); StringChange(Result, ',', '.');
      while (Result[Length(Result)] = '0')or((Result[Length(Result)] = '.')and(Pos('.', Result) > 0)) do
        SetLength(Result, Length(Result)-1);
    end;

    function MbOrTb(Float: Extended): String;
    begin
      if Float < 1024 then Result:= NumToStr(Float)+' Мб' else
        if Float/1024 < 1024 then Result:= NumToStr(Float/1024)+' Гб' else
          Result:= NumToStr(Float/(1024*1024))+' Тб';
    end;

    procedure DirEditOnChange(Sender: TObject);
    var Drive: String;
    begin
      Drive:= ExtractFileDrive(WizardForm.DirEdit.Text);
      GetSpaceOnDisk(Drive, True, FreeMB, TotalMB);
      TotalSpaceLabel.Caption:= 'Всего места на диске: '+MbOrTb(TotalMB);
      FreeSpaceLabel.Caption:= 'Доступно места на диске: '+MbOrTb(FreeMB)+' ('+IntToStr(round(FreeMB*100/TotalMB))+'%)';
      InstallSpacelabel.Caption:= 'Требуется места для установки: '+MbOrTb({#NeedInstallSize});
      NeedSpaceLabel.Caption:= 'Требуется места на диске: '+MbOrTb({#NeedSize});
      WizardForm.NextButton.Enabled:= (FreeMB>{#NeedInstallSize})and(FreeMB>{#NeedSize});
    end;

    procedure InitializeWizard();
    begin
      TotalSpaceLabel:= TLabel.Create(WizardForm);
      TotalSpaceLabel.AutoSize:= False;
      TotalSpaceLabel.SetBounds(0, 120, 300, 20);
      TotalSpaceLabel.Parent:= WizardForm.SelectDirpage;

      FreeSpaceLabel:= TLabel.Create(WizardForm);
      FreeSpaceLabel.AutoSize:= False;
      FreeSpaceLabel.SetBounds(0, 140, 300, 20);
      FreeSpaceLabel.Parent:= WizardForm.SelectDirpage;

      InstallSpacelabel:= TLabel.Create(WizardForm);
      InstallSpacelabel.AutoSize:= False;
      InstallSpacelabel.SetBounds(0, 160, 300, 20);
      InstallSpacelabel.Parent:= WizardForm.SelectDirpage;
     
      NeedSpaceLabel:= TLabel.Create(WizardForm);
      NeedSpaceLabel.AutoSize:= False;
      NeedSpaceLabel.SetBounds(0, 180, 300, 20);
      NeedSpaceLabel.Parent:= WizardForm.SelectDirpage;
     
      WizardForm.DirEdit.OnChange:=@DirEditOnChange;
    end;

    procedure CurPageChanged(CurPageID: Integer);
    begin
      if CurPageID=wpSelectDir then begin
        DirEditOnChange(nil)
      end;
    end;
     
    Craj, Gabriel, GolD20 и 4 другим нравится это.
  9. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Как получить определенное значение из INI-файла?
    О: Так. Здесь 2 примера
    Код (Text):
    [Setup]
    AppName={code:GetAppName}
    AppVerName=My Program 1.5
    AppPublisher=My Company, Inc.
    DefaultDirName={pf}\My Program
    DefaultGroupName=My Program
    OutputBaseFilename=setup

    [Languages]
    Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"

    [code]
    var
      IniValue, IniFile: String;

    //Для получения значения в другую секцию
    function GetAppName(IniFile: String): String;
    begin
      IniFile:='G:\Name.ini'
      IniValue:= GetIniString('ModuleName', 'AppName', '', IniFile);
      Result := IniValue
    end;

    //Просто получение значения
    procedure InitializeWizard();
    begin
      IniFile:='G:\Name.ini'
      IniValue:= GetIniString('ModuleName'{Название секции}, 'AppName'{Подключ}, '', IniFile{Ini файл});
      WizardForm.WelcomeLabel2.Caption := IniValue;
    end;
     
    Craj нравится это.
  10. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    Q: Как растянуть картинку на первой и последней странице?
    A: Примерно так
    Код (Text):
    [Setup]
    AppName=MyApp
    AppVerName=MyApp
    DefaultDirname={pf}\MyApp

    [code]
    var
      WelcomeLabel1, WelcomeLabel2, FinishedLabel, FinishedHeadingLabel: TLabel;
      PageNameLabel, PageDescriptionLabel: TLabel;

    procedure InitializeWizard();
    begin
      WizardForm.WizardBitmapImage.Width := ScaleX(497);
      WizardForm.WizardBitmapImage2.Width := ScaleX(497);

      { WelcomeLabel1 }
      WizardForm.WelcomeLabel1.Hide;
      WelcomeLabel1 := TLabel.Create(WizardForm);
      with WizardForm.WelcomeLabel1 do
      begin
        WelcomeLabel1.Parent := Parent;
        WelcomeLabel1.SetBounds(Left, Top, Width, Height);
        WelcomeLabel1.AutoSize := AutoSize;
        WelcomeLabel1.Font := Font;
        WelcomeLabel1.Font.Color := clWhite;
        WelcomeLabel1.Transparent := True;
        WelcomeLabel1.WordWrap := WordWrap;
        WelcomeLabel1.Caption := Caption;
      end;

      { WelcomeLabel2 }
      WizardForm.WelcomeLabel2.Hide;
      WelcomeLabel2 := TLabel.Create(WizardForm);
      with WizardForm.WelcomeLabel2 do
      begin
        WelcomeLabel2.Parent := Parent;
        WelcomeLabel2.SetBounds(Left, Top, Width, Height);
        WelcomeLabel2.AutoSize := AutoSize;
        WelcomeLabel2.Font := Font;
        WelcomeLabel2.Font.Color := clWhite;
        WelcomeLabel2.Transparent := True;
        WelcomeLabel2.WordWrap := WordWrap;
        WelcomeLabel2.Caption := Caption;
      end;

      WizardForm.WizardSmallBitmapImage.SetBounds(ScaleX(0), ScaleY(0), WizardForm.MainPanel.Width, WizardForm.MainPanel.Height);

      { PageNameLabel }
      WizardForm.PageNameLabel.Hide;
      PageNameLabel := TLabel.Create(WizardForm);
      with WizardForm.PageNameLabel do
      begin
        PageNameLabel.Parent := Parent;
        PageNameLabel.SetBounds(Left, Top, Width, Height);
        PageNameLabel.AutoSize := AutoSize;
        PageNameLabel.Font := Font;
        PageNameLabel.Font.Color := clWhite;
        PageNameLabel.Transparent := True;
        PageNameLabel.WordWrap := WordWrap;
      end;

      { PageDescriptionLabel }
      WizardForm.PageDescriptionLabel.Hide;
      PageDescriptionLabel:= TLabel.Create(WizardForm);
      with WizardForm.PageDescriptionLabel do
      begin
        PageDescriptionLabel.Parent := Parent;
        PageDescriptionLabel.SetBounds(Left, Top, Width, Height);
        PageDescriptionLabel.AutoSize := AutoSize;
        PageDescriptionLabel.Font := Font;
        PageDescriptionLabel.Font.Color := clWhite;
        PageDescriptionLabel.Transparent := True;
        PageDescriptionLabel.WordWrap := WordWrap;
      end;

      { FinishedHeadingLabel }
      WizardForm.FinishedHeadingLabel.Hide;
      FinishedHeadingLabel := TLabel.Create(WizardForm);
      with WizardForm.FinishedHeadingLabel do
      begin
        FinishedHeadingLabel.Parent := Parent;
        FinishedHeadingLabel.SetBounds(Left, Top, Width, Height);
        FinishedHeadingLabel.AutoSize := AutoSize;
        FinishedHeadingLabel.Font := Font;
        FinishedHeadingLabel.Font.Color := clWhite;
        FinishedHeadingLabel.Transparent := True;
        FinishedHeadingLabel.WordWrap := WordWrap;
        FinishedHeadingLabel.Caption := Caption;
      end;

      { FinishedLabel }
      WizardForm.FinishedLabel.Hide;
      FinishedLabel := TLabel.Create(WizardForm);
      with WizardForm.FinishedLabel do
      begin
        FinishedLabel.Parent := Parent;
        FinishedLabel.SetBounds(Left, Top, Width, Height);
        FinishedLabel.AutoSize := AutoSize;
        FinishedLabel.Font := Font;
        FinishedLabel.Font.Color := clWhite;
        FinishedLabel.Transparent := True;
        FinishedLabel.WordWrap := WordWrap;
      end;
    end;

    procedure CurPageChanged(CurPageID: Integer);
    begin
      PageNameLabel.Caption := WizardForm.PageNameLabel.Caption;
      PageDescriptionLabel.Caption := WizardForm.PageDescriptionLabel.Caption;
      FinishedLabel.Caption := WizardForm.FinishedLabel.Caption;
    end;
     
    Craj нравится это.
  11. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Как добавить проценты установки на страницу инсталляции?
    О: Так
    Код (Text):
    [Setup]
    AppName=MyApp
    AppVerName=MyApp
    DefaultDirName={pf}\MyApp

    [Files]
    Source: compiler:innocallback.dll; Flags: dontcopy
    Source: {win}\Help\*; DestDir: {app}; Flags: external recursesubdirs

    [code]
    type
        TTimerProc = procedure(HandleW, Msg, idEvent, TimeSys: LongWord);

    var
      PercentsTimer: LongWord;
      PercentsLabel: TLabel;
     
    function WrapTimerProc(callback: TTimerProc; Paramcount: Integer): longword; external 'wrapcallback@files:innocallback.dll stdcall';
    function SetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc: LongWord): longword; external 'SetTimer@user32';
    function KillTimer(hWnd, nIDEvent: LongWord): LongWord; external 'KillTimer@user32 stdcall delayload';

    Function NumToStr(Float: Extended): String;
    Begin
        Result:= Format('%.1n', [Float]); StringChange(Result, ',', '.');
        while ((Result[Length(Result)] = '0') or (Result[Length(Result)] = '.')) and (Pos('.', Result) > 0) do
            SetLength(Result, Length(Result)-1);
    End;

    Procedure PercentsProc(h, msg, idevent, dwTime: Longword);
    Begin
      with WizardForm.ProgressGauge do
      begin
        PercentsLabel.Caption:= 'Выполнено ' + NumToStr((Position*100)/Max) + ' %';
      end;
    End;

    procedure DeinitializeSetup();
    begin
        KillTimer(0, PercentsTimer);
    end;

    procedure InitializeWizard();
    begin
        PercentsLabel:= TLabel.Create(WizardForm);
      with PercentsLabel do
      begin
        Left:= WizardForm.ProgressGauge.Left;
        Top:= WizardForm.ProgressGauge.Top + WizardForm.ProgressGauge.Height + ScaleY(10);
        Width:= WizardForm.StatusLabel.Width;
        Height:= WizardForm.StatusLabel.Height;
        AutoSize:= False;
        Transparent := True;
        Parent:= WizardForm.InstallingPage;
       end;
    end;

    procedure CurStepChanged(CurStep: TSetupStep);
    begin
      if CurStep = ssInstall then
      begin
      PercentsTimer:= SetTimer(0, 0, 100, WrapTimerProc(@PercentsProc, 4));
      end;
    end;
     
    Kotyarko_O, aCHIVKA и Craj нравится это.
  12. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Как добавить TMemo на страницу установки, в котором будут отображаться извлекаемые файлы?
    О: Примерно так
    Код (Text):
    [Setup]
    AppName=MyApp
    AppVerName=MyApp
    DefaultDirName={pf}\MyApp

    [Files]
    Source: E:\Program\Inno Setup 5.3.8 Ext\*; DestDir: {app}; BeforeInstall: AddToMemo; Flags: nocompression recursesubdirs createallsubdirs

    [Code]
    var
      FilesMemo: TNewMemo;

    procedure AddToMemo();
    var
      AFile: String;
    begin
      AFile := ExpandConstant(CurrentFilename);
      if ExtractFileExt(AFile) = '' then
        FilesMemo.Lines.Add('CreateFolder: ' + RemoveBackslash(AFile))
      else
        FilesMemo.Lines.Add('Extract: ' + AFile);
    end;

    procedure InitializeWizard();
    begin
      FilesMemo := TNewMemo.Create(WizardForm);
      FilesMemo.SetBounds(ScaleX(0), ScaleY(80), ScaleX(418), ScaleY(120));
      FilesMemo.WordWrap := False;
      FilesMemo.Parent := WizardForm.InstallingPage;
      FilesMemo.ScrollBars := ssVertical;
      FilesMemo.ReadOnly := True;
      FilesMemo.Clear;
    end;
     
    Nemko, Хамик и Craj нравится это.
  13. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Как сделать проверку на количество извлеченных файлов?
    О: Так
    Код (Text):
    #define CountFiles "3"

    [Setup]
    AppName=MyApp
    AppVerName=MyApp
    DefaultDirName={pf}\MyApp

    [code]
    function GetFilesCount(Dir: String): Integer;
    var
    FSR: TFindRec;
    FindResult: Boolean;
    begin
      try
        FindResult:= FindFirst(AddBackslash(Dir)+'*.*', FSR);
        repeat
          if ((FSR.Attributes and FILE_ATTRIBUTE_DIRECTORY) = 0) then begin
            Result:= Result+1;
          end else
          if ((FSR.Attributes and FILE_ATTRIBUTE_DIRECTORY) = FILE_ATTRIBUTE_DIRECTORY)and((FSR.Name<>'.')and(FSR.Name<>'..')) then begin
            Result:=GetFilesCount(AddBackslash(Dir)+FSR.Name);
          end;
          FindResult:= FindNext(FSR);
        until not FindResult
      finally
        FindClose(FSR);
      end;
    end;

    procedure CurStepChanged(CurStep: TSetupStep);
    var Res: Integer;
    begin
    if CurStep = ssPostInstall then begin
      If GetFilesCount(ExpandConstant('{app}')) <{#CountFiles} then
        If MsgBox(ExpandConstant('{cm:Error}'), mbCriticalError , MB_OK) = IDOK then
          Exec(ExpandConstant('{uninstallexe}'), '/Silent', '', SW_SHOW, ewWaitUntilterminated, Res)
    end;
    end;

    [CustomMessages]
    Error=Во время распаковки были распакованы не все файлы!
     
    Kotyarko_O и Craj нравится это.
  14. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Как добавить свой шрифт в инсталлятор?
    О: Так
    Код (Text):
    #define Font "Edisson.ttf"
    #define FontName "Edisson"

    [Files]
    Source: {#Font}; Flags: dontcopy

    [code]
    #ifdef UNICODE
        #define A "W"
    #else
        #define A "A"
    #endif

    const
        FR_PRIVATE = $10;

    function AddFontResource(lpszFilename: String; fl, pdv: DWORD): Integer; external 'AddFontResourceEx{#A}@gdi32.dll stdcall';
    function RemoveFontResource(lpFileName: String; fl, pdv: DWORD): BOOL; external 'RemoveFontResourceEx{#A}@gdi32.dll stdcall';

    procedure InitializeWizard();
    begin
        if not FontExists('{#FontName}') then
        begin
            ExtractTemporaryFile('{#Font}');
            AddFontResource(ExpandConstant('{tmp}\{#Font}'), FR_PRIVATE, 0);
        end;
        WizardForm.Font.Name := '{#FontName}';
    end;

    procedure DeinitializeSetup();
    begin
        RemoveFontResource(ExpandConstant('{tmp}\{#Font}'), FR_PRIVATE, 0);
        WizardForm.Free;
    end;
     
    Craj, Shift85 и GolD20 нравится это.
  15. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Как "прицепить" дополнительную форму к окну инсталлятора, чтобы при перемещении дополнительная форма двигалась вместе с окном инсталлятора?
    О: Примерно так
    Код (Text):
    [Setup]
    AppName=MyApp
    AppVerName=MyApp
    DefaultDirname={pf}\MyApp

    [Files]
    Source: compiler:innocallback.dll; DestDir: {tmp}; Flags: dontcopy

    [code]
    const
      WM_MOVE = $3;

      GWL_WNDPROC = -4;
     
    type
      TCallbackProc = function(h:hWnd;Msg,wParam,lParam:Longint):Longint;
     
    function SetWindowLong(Wnd: HWnd; Index: Integer; NewLong: Longint): Longint; external 'SetWindowLongA@user32.dll stdcall';
    function WndProcCallBack(P:TCallbackProc;ParamCount:integer):LongWord; external 'wrapcallback@files:innocallback.dll stdcall';
    function CallWindowProc(lpPrevWndFunc: Longint; hWnd: HWND; Msg: UINT; wParam, lParam: Longint): Longint; external 'CallWindowProcA@user32.dll stdcall';
    function SetWindowPos(hWnd: HWND; hWndInsertAfter: HWND; X, Y, cx, cy: Integer; uFlags: UINT): BOOL; external 'SetWindowPos@user32.dll stdcall';

    var
    Form1: TForm;
    OldProc: Longint;

    function MyProc(h: HWND; Msg, wParam, lParam: longint): Longint;
    begin
      if Msg=WM_MOVE then SetWindowPos(Form1.Handle, 0, WizardForm.Left+WizardForm.Width+5, WizardForm.Top, 0, 0, $415);
      Result:= CallWindowProc(OldProc, h, Msg, wParam, lParam);
    end;

    procedure InitializeWizard();
    begin
      Form1:= TForm.Create(MainForm);
      Form1.SetBounds(WizardForm.Left+WizardForm.Width+5, WizardForm.Top, 100, 358);
      Form1.BorderStyle:= bsSingle;
      Form1.Show;
     
      OldProc:= SetWindowLong(WizardForm.Handle, GWL_WNDPROC, WndProcCallBack(@MyProc, 4));
    end;

    procedure DeinitializeSetup();
    begin
      SetWindowlong(WizardForm.Handle, GWL_WNDPROC, OldProc);
    end;
     
    Craj нравится это.
  16. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Я использовал предыдущий пример Как теперь сделать чтобы при перемещении доп. формы двигалась и основная форма?
    О: Так, данный пример на основе предыдущего примера
    Код (Text):
    [Setup]
    AppName=MyApp
    AppVerName=MyApp
    DefaultDirname={pf}\MyApp

    [Files]
    Source: compiler:innocallback.dll; DestDir: {tmp}; Flags: dontcopy

    [code]
    type
      TCallbackProc = function(h:hWnd;Msg,wParam,lParam:Longint):Longint;

    const
      WM_MOVE = $3;
      WM_ACTIVATE = $6;
      WM_CLOSE = $10;
      WM_NCACTIVATE = $86;
     
      GWL_WNDPROC = -4;
     
    function SetWindowLong(Wnd: HWnd; Index: Integer; NewLong: Longint): Longint; external 'SetWindowLongA@user32.dll stdcall';
    function WndProcCallBack(P:TCallbackProc;ParamCount:integer):LongWord; external 'wrapcallback@files:innocallback.dll stdcall';
    function CallWindowProc(lpPrevWndFunc: Longint; hWnd: HWND; Msg: UINT; wParam, lParam: Longint): Longint; external 'CallWindowProcA@user32.dll stdcall';
    function SetWindowPos(hWnd: HWND; hWndInsertAfter: HWND; X, Y, cx, cy: Integer; uFlags: UINT): BOOL; external 'SetWindowPos@user32.dll stdcall';

    var
    Form1: TForm;
    OldProc, OldProc1: Longint;

    function MyProc(h: HWND; Msg, wParam, lParam: longint): Longint;
    begin
      if Msg=WM_MOVE then SetWindowPos(Form1.Handle, 0, WizardForm.Left+WizardForm.Width+5, WizardForm.Top, 0, 0, $415);
      Result:= CallWindowProc(OldProc, h, Msg, wParam, lParam);
      if Msg=WM_ACTIVATE then SendMessage(Form1.Handle, WM_NCACTIVATE, 1, 0);
    end;

    function MyProc1(h: HWND; Msg, wParam, lParam: longint): Longint;
    begin
      if Msg=WM_MOVE then begin
        SetWindowPos(WizardForm.Handle, 0, Form1.Left-(WizardForm.Width+5), Form1.Top, 0, 0, $415);
      end;
      if Msg=WM_CLOSE then begin
        SendMessage(WizardForm.handle, WM_CLOSE, 0, 0);
        Exit;
      end;
      Result:= CallWindowProc(OldProc1, h, Msg, wParam, lParam);
      if Msg=WM_ACTIVATE then SendMessage(WizardForm.Handle, WM_NCACTIVATE, 1, 0);
    end;


    procedure InitializeWizard();
    begin
      Form1:= TForm.Create(MainForm);
      Form1.SetBounds(WizardForm.Left+WizardForm.Width+5, WizardForm.Top, 160, WizardForm.Height);
      Form1.BorderStyle:= bsSingle;
      Form1.Show;

      OldProc:= SetWindowLong(WizardForm.Handle, GWL_WNDPROC, WndProcCallBack(@MyProc, 4));
      OldProc1:= SetWindowLong(Form1.Handle, GWL_WNDPROC, WndProcCallBack(@MyProc1, 4))
    end;

    procedure DeinitializeSetup();
    begin
      SetWindowlong(WizardForm.Handle, GWL_WNDPROC, OldProc);
      SetWindowlong(Form1.Handle, GWL_WNDPROC, OldProc1);
    end;
     
    Craj нравится это.
  17. Безумный Лорд Администратор

    Регистрация:
    15 июн 2011
    Сообщения:
    671
    Симпатии:
    948
    Пол:
    Мужской
    В: Как разрешить установку продукта только на диск с файловой системой NTFS?
    О: Так
    Код (Text):
    [Setup]
    AppName=MyApp
    AppVername=MyApp
    DefaultDirName={pf}\MyApp

    [code]
    #ifdef UNICODE
      #define A "W"
    #else
      #define A "A"
    #endif

    function GetVolumeInformation(PathName, VolumeName: PAnsiChar; VolumeNameSize, VolumeSerialNumber, MaxComponentLength, FileSystemFlags: Longint; FileSystemName: PAnsiChar; FileSystemNameSize: Longint): Longint;
      external 'GetVolumeInformation{#A}@kernel32.dll stdcall';

    function NextButtonClick(CurPageID: Integer): Boolean;
    var VolumeName, FileSystemName: String;
        VolumeSerialNo, MaxComponentLength, FileSystemFlags: Longint;
    begin
      Result := True;
      if CurPageID = wpSelectDir then begin
        FileSystemName:= StringOfChar(' ', 32); VolumeName:= StringOfChar(' ', 256);
        GetVolumeInformation(PAnsiChar(ExtractFileDrive(WizardForm.DirEdit.Text)+'\'), PAnsiChar(VolumeName), 255, VolumeSerialNo, MaxComponentLength, FileSystemFlags, PAnsiChar(FileSystemName), 31);
        if Pos('NTFS', FileSystemName)=0 then begin
          MsgBox('Установка данного продукта возможна только на диск с файловой системой NTFS.'#13'Пожалуйста, измените путь установки.', mbError, mb_Ok);
          Result := False ;
        end;
      end;
    end;
     
    Craj нравится это.
  18. Ветеран Проверенный

    Регистрация:
    15 июн 2011
    Сообщения:
    42
    Симпатии:
    34
    В: Как запретить установку в папку с русскими буквами?
    О: Вот так: (Самый быстрый вариант от VoLT)
    Код (Text):
    [Setup]
    AppName=MyApp
    AppVername=MyApp
    DefaultDirName={pf}\MyApp

    [Code]
    function IsAnsi(S: String): Boolean;
    var
      S1, S2: string;
    begin
      S1 := AnsiUppercase(S);
      S2 := Uppercase(S);
      if CompareStr(S1, S2) = 0 then
      begin
        S1 := Lowercase(S);
        S2 := AnsiLowercase(S);
        if CompareStr(S1, S2) = 0 then
          Result := True;
      end;
    end;

    function NextButtonClick(CurPageID: Integer): Boolean;
    begin
      Result := True;
      if CurPageID = wpSelectDir then
      if not(IsAnsi(WizardForm.DirEdit.Text)) then
      begin
        MsgBox( 'В пути установки присуствуют русские символы'#13#13'Пожалуйста, повторите ввод.', mbError, mb_Ok);
        Result := False;
      end;
    end;
     
    ajiger, Craj, Kaktus и 4 другим нравится это.
  19. Ветеран Модератор

    Регистрация:
    26 июн 2011
    Сообщения:
    896
    Симпатии:
    614
    В: Как установить приоритет для инсталлятора?
    О: Так
    Код (Text):
    [Setup]
    AppName=MyApp
    AppVername=MyApp
    DefaultDirName={pf}\MyApp

    [code]

    const
      NORMAL_PRIORITY_CLASS           = $00000020;
      IDLE_PRIORITY_CLASS             = $00000040;
      HIGH_PRIORITY_CLASS             = $00000080;
      REALTIME_PRIORITY_CLASS         = $00000100;

    function SetPriorityClass(hProcess: THandle; dwPriorityClass: DWORD): BOOL;
      external 'SetPriorityClass@kernel32';

    function GetCurrentProcess: THandle;
      external 'GetCurrentProcess@kernel32';

    procedure InitializeWizard();
    begin
      SetPriorityClass(GetCurrentProcess, IDLE_PRIORITY_CLASS);     //установка приоритета для инсталлятора.
    end;
     
    Carlos, DICI BF, Craj и 3 другим нравится это.
  20. Старожил

    Регистрация:
    5 авг 2011
    Сообщения:
    1
    Симпатии:
    12
    В: Меняем стандартный вид папки на иконку установленной программы как в меню "Пуск" так и в "пути" установки.
    image.png
    О: Архив со скриптом и необходимыми файлами во вложении.
     

    Вложения:

    Devils Night, Comancheros, Craj и 9 другим нравится это.

Поделиться этой страницей