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

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

Тема в разделе "Inno Setup", создана пользователем TheLegend, 10 мар 2020.

  1. Пользователь

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

    Код (Inno):
    1. procedure ISDone_Unpack;                                                          
    2. begin                                                              
    3.   ISDone_Resources;          
    4.   ISDoneError := False;
    5.   if ISDoneInit(ExpandConstant('{tmp}\records.inf'), $F777, 0, 0, 0, MainForm.Handle, 512, @ProgressCallback) then
    6.   begin
    7.     ChangeLanguage('Russian');
    8.     if SrepInit('', 512, 0) and PrecompInit('', 128, 0) and FileSearchInit(true) then
    9.     begin
    10.       WizardForm.ProgressGauge.Position := 0;                                    
    11.       Wizardform.ProgressGauge.Max := 1000;                                  
    12.       if not ISArcExtract(0, 100, ExpandConstant('{src}\data1.bin'), ExpandConstant('{app}'), '', false, '', ExpandConstant('{tmp}\arc.ini'), ExpandConstant('{app}'), false) then
    13.         ISDoneError := True;
    14.     end;
    15.     ISDoneStop;
    16.   end;
    17.   if ISDoneError = True then
    18.     WizardForm.CancelButton.OnClick(nil);
    19. end;
    20.  
    21. procedure CurStepChanged(CurStep: TSetupStep);
    22. var
    23.   MsgResult: Integer;
    24. begin                                                                                
    25.   case CurStep of
    26.     ssInstall:  
    27.         begin
    28.          ISDone_Unpack;    
    29.             if ISDoneCancel=1 then
    30.         Exec(ExpandConstant('{uninstallexe}'), '/verysilent', '',SW_HIDE, ewWaitUntilTerminated, MsgResult);
    31.         end;
    32.     ssPostInstall:
    33.     begin
    34.       if ISDoneError then
    35.         Exec(ExpandConstant('{uninstallexe}'), '/verysilent', '',SW_HIDE, ewWaitUntilTerminated, MsgResult);
    36.     end;
    37.   end;
    38. end;
    39.  
    40.  
     
  2. Борода Супер модератор

    Регистрация:
    15 июн 2011
    Сообщения:
    757
    Симпатии:
    612
    Пол:
    Мужской
    {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"
     
  3. Пользователь

    Регистрация:
    5 янв 2019
    Сообщения:
    21
    Симпатии:
    5
    Дело как раз в том, что эта секция прописана, и uninstallexe запускается при нажатии отмены, но ничего не удаляет.
     
  4. Старожил

    Регистрация:
    31 мар 2015
    Сообщения:
    340
    Симпатии:
    174
    Пол:
    Мужской
    Код (Inno):
    1. procedure ISDone_Unpack;                                                        
    2. begin                                                            
    3.   ISDone_Resources;        
    4.   ISDoneError := False;
    5.   if ISDoneInit(ExpandConstant('{tmp}\records.inf'), $F777, 0, 0, 0, MainForm.Handle, 512, @ProgressCallback) then
    6.   begin
    7.     ChangeLanguage('Russian');
    8.     if SrepInit('', 512, 0) and PrecompInit('', 128, 0) and FileSearchInit(true) then
    9.     begin
    10.       WizardForm.ProgressGauge.Position := 0;                                  
    11.       Wizardform.ProgressGauge.Max := 1000;
    12.     end;                                
    13.       if not ISArcExtract(0, 100, ExpandConstant('{src}\data1.bin'), ExpandConstant('{app}'), '', false, '', ExpandConstant('{tmp}\arc.ini'), ExpandConstant('{app}'), false) then
    14. [B][I]    ISDoneError:= False;
    15.   until True;
    16.     ISDoneStop;[/I][/B]
    17.   end;
    18.  
    19.   if ISDoneError = True then
    20.     WizardForm.CancelButton.OnClick(nil);
    21. end;
    22.  
    23. procedure CurStepChanged(CurStep: TSetupStep);
    24. var
    25.   MsgResult: Integer;
    26. begin                                                                              
    27.   case CurStep of
    28.     ssInstall:
    29.         begin
    30.          ISDone_Unpack;  
    31.             if ISDoneCancel=1 then
    32.         Exec(ExpandConstant('{uninstallexe}'), '/verysilent', '',SW_HIDE, ewWaitUntilTerminated, MsgResult);
    33.         end;
    34.     ssPostInstall:
    35.     begin
    36.       if ISDoneError then
    37.         Exec(ExpandConstant('{uninstallexe}'), '/verysilent', '',SW_HIDE, ewWaitUntilTerminated, MsgResult);
    38.     end;
    39.   end;
    40. end;
    41.  
    42.  
     
  5. Пользователь

    Регистрация:
    5 янв 2019
    Сообщения:
    21
    Симпатии:
    5
    SBalykov, кажется дело не в коде с распаковкой, если для ISDone_Unpack код из isdone использовать проблема не пропадает.
    Посмотрите весь скрипт пожалуйста.
    Код (Inno):
    1. procedure ExtractTemporaryFileIfNoExist(Filename: String);
    2. begin
    3.   if not FileExists(ExpandConstant('{tmp}\' + Filename)) then
    4.     ExtractTemporaryFile(Filename);
    5. end;
    6.  
    7. procedure ISDone_Resources;
    8. begin
    9. #ifdef records
    10.   ExtractTemporaryFileIfNoExist('records.inf');
    11. #endif
    12.   ExtractTemporaryFileIfNoExist('arc.ini');
    13.   ExtractTemporaryFileIfNoExist('english.ini');
    14.   ExtractTemporaryFileIfNoExist('russian.ini');
    15.   ExtractTemporaryFileIfNoExist('unarc.dll');
    16.  
    17.   ExtractTemporaryFileIfNoExist('cls-srep.dll');
    18.   ExtractTemporaryFileIfNoExist('cls-srep_x86.exe');
    19.   ExtractTemporaryFileIfNoExist('cls-srep_x64.exe');
    20.  
    21.   ExtractTemporaryFileIfNoExist('cls-lolz.dll');
    22.   ExtractTemporaryFileIfNoExist('cls-lolz_x64.exe');
    23.   ExtractTemporaryFileIfNoExist('cls-lolz_x86.exe');
    24.      
    25.   ExtractTemporaryFileIfNoExist('CLS-MSC_TAK.dll');
    26. end;
    27.  
    28. var
    29.   ISDoneCancel: Integer;          
    30.   ISDoneError: Boolean;
    31.  
    32. type
    33.   TCallback = function (OveralPct,CurrentPct: integer;CurrentFile,TimeStr1,TimeStr2,TimeStr3:PAnsiChar): longword;
    34.  
    35. function ISArcExtract(CurComponent:Cardinal; PctOfTotal:double; InName, OutPath, ExtractedPath: AnsiString;
    36.   DeleteInFile:boolean; Password, CfgFile, WorkPath: AnsiString; ExtractPCF: boolean ):boolean;
    37.     external 'ISArcExtract@files:ISDone.dll stdcall delayload';
    38. function SrepInit(TmpPath:PAnsiChar;VirtMem,MaxSave:Cardinal):boolean;
    39.   external 'SrepInit@files:ISDone.dll stdcall delayload';
    40. function PrecompInit(TmpPath:PAnsiChar;VirtMem:cardinal;PrecompVers:single):boolean;
    41.   external 'PrecompInit@files:ISDone.dll stdcall delayload';          
    42. function FileSearchInit(RecursiveSubDir:boolean):boolean;
    43.   external 'FileSearchInit@files:ISDone.dll stdcall delayload';                                                                                                      
    44. function ISDoneInit(RecordFileName:AnsiString; TimeType,Comp1,Comp2,Comp3:Cardinal; WinHandle, NeededMem:longint; callback:TCallback):boolean;
    45.   external 'ISDoneInit@files:ISDone.dll stdcall';
    46. function ISDoneStop:boolean;
    47.   external 'ISDoneStop@files:ISDone.dll stdcall';            
    48. function ChangeLanguage(Language:AnsiString):boolean;
    49.   external 'ChangeLanguage@files:ISDone.dll stdcall delayload';        
    50. function SuspendProc:boolean;                                                          
    51.   external 'SuspendProc@files:ISDone.dll stdcall';                                                
    52. function ResumeProc:boolean;                                                        
    53.   external 'ResumeProc@files:ISDone.dll stdcall';
    54.  
    55. procedure ProgressLabels(Status, CurrentFile: String);
    56. begin
    57.   WizardForm.StatusLabel.Caption:=Status;
    58.   with WizardForm.FilenameLabel do
    59.     Caption := MinimizePathName(CurrentFile, Font, Width);
    60. end;
    61.  
    62. function ProgressCallback(OveralPct,CurrentPct: integer;CurrentFile,TimeStr1,TimeStr2,TimeStr3:PAnsiChar): longword;
    63. begin
    64.   ProgressLabels(('Распаковочка...'), CurrentFile);
    65.   if OveralPct <= WizardForm.ProgressGauge.Max then
    66.     WizardForm.ProgressGauge.Position := OveralPct;
    67.   Result := ISDoneCancel;                                                        
    68. end;
    69.  
    70. procedure ISDone_Unpack;                                                          
    71. begin                                                              
    72.   ISDone_Resources;          
    73.   ISDoneError := False;
    74.   if ISDoneInit(ExpandConstant('{tmp}\records.inf'), $F777, 0, 0, 0, MainForm.Handle, 512, @ProgressCallback) then
    75.   begin
    76.     ChangeLanguage('Russian');
    77.     if SrepInit('', 512, 0) and PrecompInit('', 128, 0) and FileSearchInit(true) then
    78.     begin
    79.       WizardForm.ProgressGauge.Position := 0;                                    
    80.       Wizardform.ProgressGauge.Max := 1000;                                  
    81.       if not ISArcExtract(0, 0, ExpandConstant('{src}\data1.bin'), ExpandConstant('{app}'), '', False, '', ExpandConstant('{tmp}\arc.ini'), ExpandConstant('{app}'), false) then
    82.         ISDoneError := True;
    83.     end;
    84.     ISDoneStop;
    85.   end;
    86.   if ISDoneError = True then
    87.     WizardForm.CancelButton.OnClick(nil);
    88. end;
    89.  
    90. procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);                                                
    91. begin
    92.   if ISDoneError then
    93.   begin
    94.     Confirm := False;
    95.     Cancel := True;
    96.     exit;
    97.   end;
    98.   SuspendProc;
    99.   Confirm := False;
    100.   Cancel := ExitSetupMsgBox;
    101.   if CurPageID = wpInstalling then
    102.   begin                                                                                                                                
    103.     if Cancel then                                            
    104.     begin              
    105.       ISDoneError := True;
    106.       ISDoneCancel := 1;  
    107.     end;                                                  
    108.   end;
    109.   ResumeProc;
    110. end;
    111.  
    112. procedure CurStepChanged(CurStep: TSetupStep);
    113. var
    114.   MsgResult: Integer;
    115. begin                                                                              
    116.   case CurStep of
    117.     ssInstall:
    118.         begin
    119.          ISDone_Unpack;  
    120.             if ISDoneCancel=1 then
    121.         Exec(ExpandConstant('{uninstallexe}'),'/verysilent','',SW_HIDE, ewWaitUntilTerminated, MsgResult);
    122.         end;
    123.     ssPostInstall:
    124.     begin
    125.       if ISDoneError then
    126.         Exec(ExpandConstant('{uninstallexe}'),'/verysilent','',SW_HIDE, ewWaitUntilTerminated, MsgResult);
    127.     end;
    128.   end;
    129. end;  

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

    Регистрация:
    17 сен 2016
    Сообщения:
    40
    Симпатии:
    5
    Пол:
    Мужской
    она отменяет действие только самой установки Inno. Если во время отработки Isdone отменять, установщик как бы не знает про файлы извлеченные сторонней библиотекой.
     
  7. Борода Супер модератор

    Регистрация:
    15 июн 2011
    Сообщения:
    757
    Симпатии:
    612
    Пол:
    Мужской
    Код (Inno):
    1. if CurPageID = wpInstalling then
    2.   begin                                                                                                                              
    3.     if Cancel then                                          
    4.     begin            
    5.       ISDoneError := True;
    6.       ISDoneCancel := 1;
    7.     end;                                                
    8.   end;
    procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean); var - означает, что значения мы будем присваивать, брать его не получится, там значения по умолчанию. Для типа Boolean, значение по умолчанию - False.
     
    TheLegend нравится это.
  8. Борода Супер модератор

    Регистрация:
    15 июн 2011
    Сообщения:
    757
    Симпатии:
    612
    Пол:
    Мужской
    Код (Inno):
    1. procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
    2. begin
    3.   if CurPageID = wpInstalling then
    4.   begin
    5.     SuspendProc;
    6.     if MsgBox(SetupMessage(msgExitSetupMessage), mbConfirmation, MB_YESNO) = IDYES then ISDoneCancel:=1;
    7.     ResumeProc;
    8.   end else
    9.   begin
    10.     Confirm := False;
    11.     Cancel := ExitSetupMsgBox;
    12.   end;
    13. end;
    14.  
     
    SBalykov нравится это.
  9. Пользователь

    Регистрация:
    5 янв 2019
    Сообщения:
    21
    Симпатии:
    5
    Думаю это не сработает, не просто так в примере isdone своя кнопка
     
  10. Борода Супер модератор

    Регистрация:
    15 июн 2011
    Сообщения:
    757
    Симпатии:
    612
    Пол:
    Мужской
    Ты попробуй ) В isdone всего лишь пример, человек в принципе не сильно заморачивался со скриптом, просто раскрыл в нем все возможности библиотеки. в своем примере я полностью заменил действие кнопки отмены на отмену из isdone для страницы установки.
     
  11. Ветеран Модератор

    Регистрация:
    26 июн 2011
    Сообщения:
    1.336
    Симпатии:
    874
    Код (Inno):
    1. procedure CancelOnCloseQuery(Sender: TObject; var CanClose: Boolean);
    2. begin
    3.   SuspendProc;
    4. if MsgBox(SetupMessage(msgExitSetupMessage), mbConfirmation, MB_YESNO) = IDYES then
    5.   ISDoneCancel:=1;
    6.   ResumeProc;
    7.   CanClose:= False;
    8. end;
    9.  
    10. procedure FOnCloseQuery(Sender: TObject; var CanClose: Boolean);
    11. begin
    12.   CanClose:= False;
    13. end;
    14.  
    15. //...
    16. if CurStep = ssPostInstall then begin  //Если необходимо, можно поменять на ssInstall
    17.   WizardForm.OnCloseQuery:= @CancelOnCloseQuery;
    18. //...
    19. procedure CurPageChanged(CurPageID: Integer);
    20. begin
    21.   case CurPageID of
    22.     wpFinished:
    23.     begin
    24.       WizardForm.OnCloseQuery:= @FOnCloseQuery;
    25. //...
    По мне так правильнее... :morning:
     
  12. Старожил

    Регистрация:
    31 мар 2015
    Сообщения:
    340
    Симпатии:
    174
    Пол:
    Мужской
    Вопрос не в закрытии формы, а в отмене установки...
    LexBell дал вполне рабочий пример...
     
  13. Ветеран Модератор

    Регистрация:
    26 июн 2011
    Сообщения:
    1.336
    Симпатии:
    874
    В примере, что дал, отмена будет происходить при wm_close (а это - крестик, alt+f4, кнопочка...). Вы можете и на кнопочке сидеть, я не против )
     
  14. Борода Супер модератор

    Регистрация:
    15 июн 2011
    Сообщения:
    757
    Симпатии:
    612
    Пол:
    Мужской
    в моем примере используется штатный механизм отмены. там работать будет все.
     
    SBalykov нравится это.
  15. Пользователь

    Регистрация:
    5 янв 2019
    Сообщения:
    21
    Симпатии:
    5
    LexBell, немного модифицировал и использовал рабочий вариант от sergey3695, а Ваш, со стандартной кнопкой, как и мой, не удаляет файлы при отмене.
     
  16. Ветеран Модератор

    Регистрация:
    26 июн 2011
    Сообщения:
    1.336
    Симпатии:
    874
    TheLegend,
    Код (Inno):
    1.  
    2. procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
    3. begin
    4.   if CurPageID = wpInstalling then
    5.   begin
    6.     SuspendProc;
    7.     if ExitSetupMsgBox then ISDoneCancel:=1;
    8.     ResumeProc;
    9.     Confirm := False;
    10.     Cancel := False;
    11.   end;
    12. end;
    13.  
    ExitSetupMsgBox сообщение о выходе (https://jrsoftware.org/ishelp/index.php?topic=isxfunc_exitsetupmsgbox). По факту там 2 сообщения о выходе. Я собрал пример isdone и проверил код, в принципе работает (не спорю), но 2-ое сообщение уже лишнее.
     
    Последнее редактирование: 13 мар 2020

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