Jump to content
Korean Random

Создание инсталляторов для модпаков на базе Inno Setup


Recommended Posts

Ребята посоветуйте, файлы копируются из секции [Files], но вычищают каталог куда копируются. А надо чтоб добавлялось. Как такое сделать? Когда была версия Unicode, то вроде нормально было. А на ansi сейчас такой глюк. Или я что не верно делаю?

Link to comment
Short link
Share on other sites

Случается так, что нужно добавить ещё одну страницу с информацией. Да не просто так, а что бы она считывалась с txt или rtf.

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

[Setup]
LicenseFile=License.rtf
InfoBeforeFile=InfoBefore.rtf
InfoAfterFile=InfoAfter.rtf
Представляю код, который добавляет ещё одну станицу, на которой есть возможность выводить текст из файла:

[Files]
Source: "ChangeLog.rtf"; DestDir: "{tmp}"; Flags: dontcopy;

[_________Code]
var
  ChangeLogPage: TOutputMsgMemoWizardPage;

procedure InitializeWizard();
var 
  ChangeLogText: AnsiString;
begin
  ChangeLogPage:=CreateOutputMsgMemoPage(wpLicense, '', '', SetupMessage(msgInfoBeforeClickLabel), '');
  ExtractTemporaryFile('ChangeLog.rtf');
  LoadStringFromFile(ExpandConstant('{tmp}/ChangeLog.rtf'), ChangeLogText);
  ChangeLogPage.RichEditViewer.RTFText:= ChangeLogText;
end;
Всё понятно и без пояснений.

 

З.Ы. Использование rtf-файлов даёт огромное преимущество - в них можно легко использовать большинство символов, форматирование абзацев и строк. Работа с ними может вестись как в Microsoft Word, так и в стандартном WordPad.

  • Upvote 5
Link to comment
Short link
Share on other sites

Вроде доделал. Объясняю как работает:

Через #include подключается файл, в котором описаны функции работы с файлами и папками. В частности тут это - MoveDir. Нужна версия Inno Setup с установленным препроцессором.

Страница создаётся после начальной. Выбираете действие и спокойно идете дальше по установке. Как только инсталлятор переходит на процесс установки (страница ssInstall) запускается чекер, который смотрит какой пункт был выбран и исходя из этого запускает нужную функцию на исполнение. В первом варианте удаляются папки 0.8.11 и xvm, потом создаётся пустая папка 0.8.11. Во втором варианте папки 0.8.11 и xvm переносятся в res_mods\backup. После создаётся пустая папка 0.8.11. Третий вариант создаётся как "заглушка", ничего не происходит при его выборе.

Если не нужны надписи вверху страницы (там где картинка), то оставляйте пустые кавычки в строке:

BackupPage:=CreateCustomPage(wpWelcome, '', '');
Тогда нужно будет ещё скрыть белый фон, на котором эти надписи отображаются. В InitializeWizard() добавьте:

WizardForm.PageNameLabel.Hide;
WizardForm.PageDescriptionLabel.Hide;
Поле этого страница будет выглядить примерно вот так:

7a11cfb9f052.png

В общем спрашивайте, если что-то не понятно. Вроде всё доступно написал.

 

не подскажешь как сделать, чтобы страница с выбором было после выбора пути к папке с игрой

Ещё вопрос:

'код'

[Setup]
DefaultDirName={code:GetInstallDir}

[Code]
Function GetInstallDir(Path: String ): String;
begin
RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1EAC1D02-C6AC-4FA6-9A44-96258C37C812CT}_is1', 'InstallLocation', Path);
Result =:Path;
end;

procedure CurPageChanged(CurPageID: Integer);
begin
 if CurPageID=wpSelectDir then
 if not RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1EAC1D02-C6AC-4FA6-9A44-96258C37C812CT}_is1') then
 begin
  if not RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1EAC1D02-C6AC-4FA6-9A44-96258C37C812CT}_is1') then
  begin
   MsgBox('Программа установки не смогла обнаружить "World_of_Tanks"!' #13#13
   'Укажите путь к игре самостоятельно.', mbInformation, mb_ok);
  end
 end
end;

 В итоге, какой бы путь я не указывал, в конце создаётся Новая_папка:

'вот так'

 

Что не так?

AppendDefaultDirName = no

Link to comment
Short link
Share on other sites

Иннот, это обычный ZIP-архив. А что нужно сделать? Можно написать автоматический скрипт, если знать фронт работ.

в самолётах разрабы гады, теперь флэшка и питон через res_mods не работают

приходиться распаковывать пак в res_mods и убирать строку на пак в path.xml

 

кодика у тебя не найдётся на сию причуду? а то скоро патч

Edited by Иннот
Link to comment
Short link
Share on other sites

Иннот, можно сделать. Только нужно обновить клиент.

 

З.Ы. Только писать буду на самом примитиве. А то можно подключать целые библиотеки с выводом процесса распаковки. Это уж точно не нужно никому.

Edited by AtotIK
Link to comment
Short link
Share on other sites

Парни!Будте добры,сделайте видео урок по созданию расширеного инстолятора с нуля!Очень много людей будут благодарны,в том числе и я!


и подскажите как объеденить скрипты которые были выложены в примере в первом посте?или как открыть этот пример в inno?

  • Upvote 2
Link to comment
Short link
Share on other sites

Иннот, держи. Рабочий вариант, без излишеств. Какие архивы распаковывать уже сам решишь, делал для примера с gui.pkg.

Как работает: Распаковка осуществляется при помощи unzip.exe, файл после установки автоматически удалится из папки. Перед копированием изменённого paths.xml делается резервная копия оригинала в "Install_Modpack\Backup", дальше выполняется распаковка файла gui.pkg. После распаковки начинается установка. При удалении анинсталлер возвращает на место оригинальный paths.xml и чистит всё, что натворил при распаковке gui.pkg.

Для удобства анинсталлер перемещён в "%папка_установки%\Install_Modpack".

Скачать:

 

Update: сделал проверку на x64/x86 систему. При этом копируется определённый unzip.

unZIP.zip

Edited by AtotIK
  • Upvote 3
Link to comment
Short link
Share on other sites

Иннот, держи. Рабочий вариант, без излишеств. Какие архивы распаковывать уже сам решишь, делал для примера с gui.pkg.

Как работает: Распаковка осуществляется при помощи unzip.exe, файл после установки автоматически удалится из папки. Перед копированием изменённого paths.xml делается резервная копия оригинала в "Install_Modpack\Backup", дальше выполняется распаковка файла gui.pkg. После распаковки начинается установка. При удалении анинсталлер возвращает на место оригинальный paths.xml и чистит всё, что натворил при распаковке gui.pkg.

Для удобства анинсталлер перемещён в "%папка_установки%\Install_Modpack".

Скачать:

Thank you

Link to comment
Short link
Share on other sites

Парни!Будте добры,сделайте видео урок по созданию расширеного инстолятора с нуля!Очень много людей будут благодарны,в том числе и я!

и подскажите как объеденить скрипты которые были выложены в примере в первом посте?или как открыть этот пример в inno?

Я не могу сказать, что я профи стал. Но мне хватило 2 вечеров посидеть в справке Inno Setup, посмотрел примеры кодов и вуаля) Просто нужно самому доходить до всего, а видео уроки тут мало научат, имхо

Edited by Melkop
  • Downvote 1
Link to comment
Short link
Share on other sites

AtotIK,   помоги пример адаптировать:

// Бэкап папки с проверкой её существования, не бэкапим повторно (с выводом чекбокса)
#define CUR_DIR "main" ;Глобально: папка, откуда копируем.
#define BAK_DIR "_backup" ;Глобально: папка, куда копируем.

[setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
OutputDir=.


[Files]
Source: C:\Windows\Fonts\*; DestDir: {app}\main; Flags: external overwritereadonly ignoreversion;


#define A = (Defined UNICODE) ? "W" : "A"

function CopyFile(lpExistingFileName, lpNewFileName: String; bFailIfExists: BOOL): BOOL; external 'CopyFile{#A}@kernel32.dll stdcall';

var
    backupChk: TCheckBox;


procedure IsBackup(const FromDir: String; const ToDir: String);
var
    fileArray: array of String;
    FindFiles: TFindRec;
    i, Len: Integer;
begin
    fileArray := ['*'];
    Len := GetArrayLength(fileArray) - 1;
    for i := 0 to Len do
    begin
        if FindFirst(FromDir + fileArray[i], FindFiles) then
        try
            WizardForm.ProgressGauge.Hide;
            WizardForm.StatusLabel.Caption := 'Создание резервной копии файлов...';

            repeat
                if not DirExists(ToDir) then CreateDir(ToDir);
                  CopyFile(FromDir + FindFiles.Name, ToDir + FindFiles.Name, False);
            until not FindNext(FindFiles);
        finally

            WizardForm.ProgressGauge.Show;
            FindClose(FindFiles);
        end;
    end;
end;

procedure InitializeWizard();
var
    ThereIsFolders: Boolean;
begin
    backupChk := nil;
    ThereIsFolders := (DirExists(AddBackslash(WizardDirValue()) + '{#CUR_DIR}') and //Проверяем, есть ли папка, откуда копируем файлы.
                      (not DirExists(AddBackslash(WizardDirValue()) + '{#BAK_DIR}')) ); //Проверяем, что папка, куда копируем файлы не существует.

    if ThereIsFolders then //Если оба вышеозначенных условия соблюдены создаем чекбокс.
    begin
        backupChk := TCheckBox.Create(nil);
        with backupChk do
        begin
            Parent := WizardForm.SelectDirPage;
            SetBounds(ScaleX(WizardForm.DirEdit.Left), ScaleY(WizardForm.DiskSpaceLabel.Top div 2), ScaleX(WizardForm.DirEdit.Width), ScaleY(15));
            Caption := 'Сохранить резервную копию перезаписываемых файлов';
            Checked := ThereIsFolders;
        end;
    end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
    case CurStep of
        ssInstall: if backupChk <> nil then //Проверяем, создан ли чекбокс.
                     if backupChk.Checked then //Если чекбокс создан, проверяем отмечен ли он
                       //Вызываем процедуру создания резервной копии файлов нв этапе перед установкой.
                       IsBackup(ExpandConstant('{app}\{#CUR_DIR}\'), //Папка, откуда копируем файлы.
                       ExpandConstant('{app}\{#BAK_DIR}\')); //Папка, куда копируем файлы.
    end;
end;

Нужно без всяких чекбоксов в обязательном порядке проверять наличие бэкапа.
Бэкапим папку:      World_of_Tanks\res\scripts\
 

  • Upvote 1
Link to comment
Short link
Share on other sites

-zav-, процедуру InitializeWizard удаляй, заменяй CurStepChanged на следующее:

procedure CurStepChanged(CurStep: TSetupStep);
var
    ThereIsFolders: Boolean;
begin
    ThereIsFolders := (DirExists(AddBackslash(WizardDirValue()) + '{#CUR_DIR}') and (not DirExists(AddBackslash(WizardDirValue()) + '{#BAK_DIR}')) );
    if ThereIsFolders then
    if CurStep=ssInstall then
    IsBackup(ExpandConstant('{app}\{#CUR_DIR}\'), ExpandConstant('{app}\{#BAK_DIR}\'));
end;

Остальное без изменений. Однако тут есть существенный недостаток: бэкапятся только файлы в самой папке, из вложенных ничего не копируется. Проще тогда взять CopyDir из моего примера и реализовать тут.

Edited by AtotIK
Link to comment
Short link
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...