Проблема Не удаляются файлы при отмене распаковки

TheLegend

Новичок
друзья, вопрос в названии, isdone ниже, lolz+srep, что-то не видел такой проблемы в репаках, удалять вручную? :acute:
[UninstallDelete]
Type: filesandordirs; Name: {app};

Код:
procedure ISDone_Unpack;                                                           
begin                                                               
  ISDone_Resources;           
  ISDoneError := False;
  if ISDoneInit(ExpandConstant('{tmp}\records.inf'), $F777, 0, 0, 0, MainForm.Handle, 512, @ProgressCallback) then
  begin
    ChangeLanguage('Russian');
    if SrepInit('', 512, 0) and PrecompInit('', 128, 0) and FileSearchInit(true) then
    begin
      WizardForm.ProgressGauge.Position := 0;                                     
      Wizardform.ProgressGauge.Max := 1000;                                   
      if not ISArcExtract(0, 100, ExpandConstant('{src}\data1.bin'), ExpandConstant('{app}'), '', false, '', ExpandConstant('{tmp}\arc.ini'), ExpandConstant('{app}'), false) then
        ISDoneError := True;
    end;
    ISDoneStop;
  end;
  if ISDoneError = True then
    WizardForm.CancelButton.OnClick(nil);
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  MsgResult: Integer;
begin                                                                                
  case CurStep of
    ssInstall:  
        begin
         ISDone_Unpack;    
            if ISDoneCancel=1 then
        Exec(ExpandConstant('{uninstallexe}'), '/verysilent', '',SW_HIDE, ewWaitUntilTerminated, MsgResult);
        end;
    ssPostInstall:
    begin
      if ISDoneError then
        Exec(ExpandConstant('{uninstallexe}'), '/verysilent', '',SW_HIDE, ewWaitUntilTerminated, MsgResult);
    end;
  end;
end;
 

LexBell

Борода
Супер модератор
{uninstallexe} удалит только то, что установит сам инсталлятор, нужно вручную удалять.
нужно добавить секцию
[UninstallDelete]
Type: filesandordirs; Name: "{app}"
Секция [UninstallDelete]
Эта секция не обязательна. В ней указываются дополнительные файлы или папки, которые деинсталлятор должен удалить, включая те из них, которые были установлены/созданы с помощью параметров секций [Files] или [Dirs]. Главным образом эта секция используется для удаления .INI файлов, созданных вашим приложением. Деинсталлятор выполняет эти параметры в конце деинсталляции.

Пример секции [UninstallDelete]:

[UninstallDelete]
Type: files; Name: "{win}\MYPROG.INI"
Список поддерживаемых параметров:

Type (Обязательно)
Указывает тип удаляемого объекта. Может быть следующим:

files
Параметр Name указывает имя отдельного файла или маску.

filesandordirs
Функции те же, что и у files за исключением, что также может задавать имя папки, в этом случае удаляются все ее файлы и подпапки.

dirifempty
При использовании этого типа параметр Name должен задавать папку, но не содержать масок. Папка будет удалена только если она пустая.

Например:
Type: files
Name (Обязательно)
Имя удаляемого файла или папки.

Внимание! Не торопитесь использовать здесь маски для удаления всех файлов папки {app}. Строго рекомендуется не делать этого по двум причинам. Во-первых, пользователи обычно не любят, когда данные, введенные ими в директории приложения, удаляются без предупреждения (они могут удалить их просто потому, что хотят, например, переместить программу в папку на другом диске). Будет лучше оставить файлы, чтобы при желании пользователь потом сам удалил их. Во-вторых, если пользователь по ошибке установил приложение не в ту папку (например, в C:\WINDOWS) и потом удалил его оттуда, это может привести к плачевным последствиям. Так что НЕ ДЕЛАЙТЕ ЭТОГО!

Например:
Name: "{win}\MYPROG.INI"
 

TheLegend

Новичок
Дело как раз в том, что эта секция прописана, и uninstallexe запускается при нажатии отмены, но ничего не удаляет.
 

SBalykov

Старожил
друзья, вопрос в названии, isdone ниже, lolz+srep, что-то не видел такой проблемы в репаках, удалять вручную? :acute:

[UninstallDelete]
Type: filesandordirs; Name: {app};
Код:
procedure ISDone_Unpack;                                                         
begin                                                             
  ISDone_Resources;         
  ISDoneError := False;
  if ISDoneInit(ExpandConstant('{tmp}\records.inf'), $F777, 0, 0, 0, MainForm.Handle, 512, @ProgressCallback) then
  begin
    ChangeLanguage('Russian');
    if SrepInit('', 512, 0) and PrecompInit('', 128, 0) and FileSearchInit(true) then
    begin
      WizardForm.ProgressGauge.Position := 0;                                   
      Wizardform.ProgressGauge.Max := 1000;
    end;                                 
      if not ISArcExtract(0, 100, ExpandConstant('{src}\data1.bin'), ExpandConstant('{app}'), '', false, '', ExpandConstant('{tmp}\arc.ini'), ExpandConstant('{app}'), false) then
[B][I]    ISDoneError:= False;
  until True;
    ISDoneStop;[/I][/B]
  end;

  if ISDoneError = True then
    WizardForm.CancelButton.OnClick(nil);
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  MsgResult: Integer;
begin                                                                              
  case CurStep of
    ssInstall:
        begin
         ISDone_Unpack;  
            if ISDoneCancel=1 then
        Exec(ExpandConstant('{uninstallexe}'), '/verysilent', '',SW_HIDE, ewWaitUntilTerminated, MsgResult);
        end;
    ssPostInstall:
    begin
      if ISDoneError then
        Exec(ExpandConstant('{uninstallexe}'), '/verysilent', '',SW_HIDE, ewWaitUntilTerminated, MsgResult);
    end;
  end;
end;
 

TheLegend

Новичок
SBalykov, кажется дело не в коде с распаковкой, если для ISDone_Unpack код из isdone использовать проблема не пропадает.
Посмотрите весь скрипт пожалуйста.
Код:
procedure ExtractTemporaryFileIfNoExist(Filename: String);
begin
  if not FileExists(ExpandConstant('{tmp}\' + Filename)) then
    ExtractTemporaryFile(Filename);
end;

procedure ISDone_Resources;
begin
#ifdef records
  ExtractTemporaryFileIfNoExist('records.inf');
#endif
  ExtractTemporaryFileIfNoExist('arc.ini');
  ExtractTemporaryFileIfNoExist('english.ini'); 
  ExtractTemporaryFileIfNoExist('russian.ini');
  ExtractTemporaryFileIfNoExist('unarc.dll');

  ExtractTemporaryFileIfNoExist('cls-srep.dll'); 
  ExtractTemporaryFileIfNoExist('cls-srep_x86.exe');
  ExtractTemporaryFileIfNoExist('cls-srep_x64.exe');

  ExtractTemporaryFileIfNoExist('cls-lolz.dll'); 
  ExtractTemporaryFileIfNoExist('cls-lolz_x64.exe');
  ExtractTemporaryFileIfNoExist('cls-lolz_x86.exe');
      
  ExtractTemporaryFileIfNoExist('CLS-MSC_TAK.dll');
end;

var
  ISDoneCancel: Integer;           
  ISDoneError: Boolean; 

type
  TCallback = function (OveralPct,CurrentPct: integer;CurrentFile,TimeStr1,TimeStr2,TimeStr3:PAnsiChar): longword;

function ISArcExtract(CurComponent:Cardinal; PctOfTotal:double; InName, OutPath, ExtractedPath: AnsiString;
  DeleteInFile:boolean; Password, CfgFile, WorkPath: AnsiString; ExtractPCF: boolean ):boolean;
    external 'ISArcExtract@files:ISDone.dll stdcall delayload';
function SrepInit(TmpPath:PAnsiChar;VirtMem,MaxSave:Cardinal):boolean;
  external 'SrepInit@files:ISDone.dll stdcall delayload';
function PrecompInit(TmpPath:PAnsiChar;VirtMem:cardinal;PrecompVers:single):boolean;
  external 'PrecompInit@files:ISDone.dll stdcall delayload';           
function FileSearchInit(RecursiveSubDir:boolean):boolean;
  external 'FileSearchInit@files:ISDone.dll stdcall delayload';                                                                                                      
function ISDoneInit(RecordFileName:AnsiString; TimeType,Comp1,Comp2,Comp3:Cardinal; WinHandle, NeededMem:longint; callback:TCallback):boolean;
  external 'ISDoneInit@files:ISDone.dll stdcall';
function ISDoneStop:boolean;
  external 'ISDoneStop@files:ISDone.dll stdcall';            
function ChangeLanguage(Language:AnsiString):boolean;
  external 'ChangeLanguage@files:ISDone.dll stdcall delayload';        
function SuspendProc:boolean;                                                          
  external 'SuspendProc@files:ISDone.dll stdcall';                                                 
function ResumeProc:boolean;                                                         
  external 'ResumeProc@files:ISDone.dll stdcall'; 

procedure ProgressLabels(Status, CurrentFile: String);
begin
  WizardForm.StatusLabel.Caption:=Status;
  with WizardForm.FilenameLabel do
    Caption := MinimizePathName(CurrentFile, Font, Width);
end;

function ProgressCallback(OveralPct,CurrentPct: integer;CurrentFile,TimeStr1,TimeStr2,TimeStr3:PAnsiChar): longword;
begin
  ProgressLabels(('Распаковочка...'), CurrentFile);
  if OveralPct <= WizardForm.ProgressGauge.Max then
    WizardForm.ProgressGauge.Position := OveralPct;
  Result := ISDoneCancel;                                                         
end;

procedure ISDone_Unpack;                                                          
begin                                                              
  ISDone_Resources;          
  ISDoneError := False;
  if ISDoneInit(ExpandConstant('{tmp}\records.inf'), $F777, 0, 0, 0, MainForm.Handle, 512, @ProgressCallback) then
  begin
    ChangeLanguage('Russian');
    if SrepInit('', 512, 0) and PrecompInit('', 128, 0) and FileSearchInit(true) then
    begin
      WizardForm.ProgressGauge.Position := 0;                                    
      Wizardform.ProgressGauge.Max := 1000;                                  
      if not ISArcExtract(0, 0, ExpandConstant('{src}\data1.bin'), ExpandConstant('{app}'), '', False, '', ExpandConstant('{tmp}\arc.ini'), ExpandConstant('{app}'), false) then
        ISDoneError := True;
    end;
    ISDoneStop;
  end;
  if ISDoneError = True then
    WizardForm.CancelButton.OnClick(nil);
end;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);                                                 
begin
  if ISDoneError then
  begin
    Confirm := False;
    Cancel := True;
    exit;
  end;
  SuspendProc;
  Confirm := False;
  Cancel := ExitSetupMsgBox;
  if CurPageID = wpInstalling then
  begin                                                                                                                                 
    if Cancel then                                             
    begin              
      ISDoneError := True;
      ISDoneCancel := 1;   
    end;                                                   
  end;
  ResumeProc;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  MsgResult: Integer;
begin                                                                               
  case CurStep of
    ssInstall: 
        begin
         ISDone_Unpack;   
            if ISDoneCancel=1 then
        Exec(ExpandConstant('{uninstallexe}'),'/verysilent','',SW_HIDE, ewWaitUntilTerminated, MsgResult);
        end;
    ssPostInstall:
    begin
      if ISDoneError then
        Exec(ExpandConstant('{uninstallexe}'),'/verysilent','',SW_HIDE, ewWaitUntilTerminated, MsgResult);
    end;
  end;
end;

UPD. Проблема с кнопкой отмены, с тем, что я хотел использовать стандартную, кастомная работает, но что не так со стандартной?
 
Последнее редактирование:

Andreo Fadio

Ветеран
Проблема с кнопкой отмены, с тем, что я хотел использовать стандартную, кастомная работает, но что не так со стандартной?
она отменяет действие только самой установки Inno. Если во время отработки Isdone отменять, установщик как бы не знает про файлы извлеченные сторонней библиотекой.
 

LexBell

Борода
Супер модератор
Код:
if CurPageID = wpInstalling then
  begin                                                                                                                              
    if Cancel then                                          
    begin            
      ISDoneError := True;
      ISDoneCancel := 1;
    end;                                                
  end;
procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean); var - означает, что значения мы будем присваивать, брать его не получится, там значения по умолчанию. Для типа Boolean, значение по умолчанию - False.
 

LexBell

Борода
Супер модератор
Код:
procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
  if CurPageID = wpInstalling then
  begin
    SuspendProc;
    if MsgBox(SetupMessage(msgExitSetupMessage), mbConfirmation, MB_YESNO) = IDYES then ISDoneCancel:=1;
    ResumeProc;
  end else
  begin
    Confirm := False;
    Cancel := ExitSetupMsgBox;
  end;
end;
 

LexBell

Борода
Супер модератор
Думаю это не сработает, не просто так в примере isdone своя кнопка
Ты попробуй ) В isdone всего лишь пример, человек в принципе не сильно заморачивался со скриптом, просто раскрыл в нем все возможности библиотеки. в своем примере я полностью заменил действие кнопки отмены на отмену из isdone для страницы установки.
 

sergey3695

Ветеран
Модератор
Код:
procedure CancelOnCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  SuspendProc;
if MsgBox(SetupMessage(msgExitSetupMessage), mbConfirmation, MB_YESNO) = IDYES then
  ISDoneCancel:=1;
  ResumeProc;
  CanClose:= False;
end;

procedure FOnCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose:= False;
end;

//...
if CurStep = ssPostInstall then begin  //Если необходимо, можно поменять на ssInstall
  WizardForm.OnCloseQuery:= @CancelOnCloseQuery;
//...
procedure CurPageChanged(CurPageID: Integer);
begin
  case CurPageID of
    wpFinished:
    begin
      WizardForm.OnCloseQuery:= @FOnCloseQuery;
//...
По мне так правильнее... :morning:
 

SBalykov

Старожил
Код:
procedure CancelOnCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  SuspendProc;
if MsgBox(SetupMessage(msgExitSetupMessage), mbConfirmation, MB_YESNO) = IDYES then
  ISDoneCancel:=1;
  ResumeProc;
  CanClose:= False;
end;

procedure FOnCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose:= False;
end;

//...
if CurStep = ssPostInstall then begin  //Если необходимо, можно поменять на ssInstall
  WizardForm.OnCloseQuery:= @CancelOnCloseQuery;
//...
procedure CurPageChanged(CurPageID: Integer);
begin
  case CurPageID of
    wpFinished:
    begin
      WizardForm.OnCloseQuery:= @FOnCloseQuery;
//...
По мне так правильнее... :morning:
Вопрос не в закрытии формы, а в отмене установки...
LexBell дал вполне рабочий пример...
 

LexBell

Борода
Супер модератор
В примере, что дал, отмена будет происходить при wm_close (а это - крестик, alt+f4, кнопочка...). Вы можете и на кнопочке сидеть, я не против )
в моем примере используется штатный механизм отмены. там работать будет все.
 

TheLegend

Новичок
LexBell, немного модифицировал и использовал рабочий вариант от sergey3695, а Ваш, со стандартной кнопкой, как и мой, не удаляет файлы при отмене.
 

sergey3695

Ветеран
Модератор
TheLegend,
Код:
procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
  if CurPageID = wpInstalling then
  begin
    SuspendProc;
    if ExitSetupMsgBox then ISDoneCancel:=1;
    ResumeProc;
    Confirm := False;
    Cancel := False;
  end;
end;
дал вполне рабочий пример...
там работать будет все.
ExitSetupMsgBox сообщение о выходе (https://jrsoftware.org/ishelp/index.php?topic=isxfunc_exitsetupmsgbox). По факту там 2 сообщения о выходе. Я собрал пример isdone и проверил код, в принципе работает (не спорю), но 2-ое сообщение уже лишнее.
 
Последнее редактирование:
Сверху