Информация Удаление файлов по логу установки. (Решено)

Xenium

Новичок
День добрый, прошу помощи, как сделать чтобы Uninstall удалял только файлы из списка install.log?
Например пользователь установил Mod для игры и захотел его удалить, на текущий момент удалится вся игра вместе с модом, чего как раз необходимо избежать.

Имеется код, который "должен" работать как описано, но он либо не удаляет файлы из списка, либо удаляет всю папку целиком.
(Полный код в закрепе)
Заранее спасибо.

Код:
[UninstallDelete]
Type: filesandordirs; Name: {app}

Код:
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
  var
    i : Integer;
begin
  if CurUninstallStep = usPostUninstall then
    if ULog then
    begin
      for i := 0 to unins_list.Count-1 do DeleteFile(unins_list[i]); // удаляем файлы из списка
      unins_list.Free;
    end;
end;
 

Вложения

sergey3695

Ветеран
Модератор
@Xenium,
изменил записываемый путь
code_language.pascal:
  ins_log.Add(AddBackslash(ExpandConstant('{app}')) + CurrentFile); // тут пишем файл в лог
и задал создание лога после установки
code_language.pascal:
  if CurStep = ssPostInstall then begin
    ins_log.Add(ExpandConstant('{app}\INSTALL.LOG'));
      ins_log.SaveToFile(ExpandConstant('{app}\INSTALL.LOG')); // сохраняем лог
    ins_log.Free;
  end;
с unarc в архиве не распаковывало архив, заменил на последний.
 

Вложения

Xenium

Новичок
@Xenium,
изменил записываемый путь
code_language.pascal:
  ins_log.Add(AddBackslash(ExpandConstant('{app}')) + CurrentFile); // тут пишем файл в лог
и задал создание лога после установки
code_language.pascal:
  if CurStep = ssPostInstall then begin
    ins_log.Add(ExpandConstant('{app}\INSTALL.LOG'));
      ins_log.SaveToFile(ExpandConstant('{app}\INSTALL.LOG')); // сохраняем лог
    ins_log.Free;
  end;
с unarc в архиве не распаковывало архив, заменил на последний.
Спасибо, теперь это работает! Почти как надо)


Архив распаковывает следующие файлы:
dxwebsetup - 256kb
NET_Framework_4.5.1_Setup - 68mb
VCRHyb64 - 47mb

Но лог всегда разный, причем никогда не содержит dxwebsetup
Код:
E:\Games\ISDone\INSTALL.LOG
E:\Games\ISDone\VCRHyb64.exe
 

sergey3695

Ветеран
Модератор
@Xenium,
Cделай удаление по заранее подготовленному логу тогда.
Батник создаст INSTALL.LOG с перечнем файлов без корневого пути. В инно грузишь в stringlist, если есть файл и перебором удаляешь.
Код:
@Echo Off
SetLocal EnableDelayedExpansion
Set DataRoot=%~dp0
Set OutFile=INSTALL.LOG
For /F "delims=" %%A In ('Dir "%DataRoot%\*.*" /B /S /A-D 2^>nul') Do (
  Set str=%%A
  Set stra=!str:%~dp0=!
  Echo !stra!>>"%OutFile%")
Pause
code_language.pascal:
var
  i:integer;
  SvfList: TStringlist;
  str: string;
begin
  SvfList := TStringList.Create;
  SvfList.LoadFromFile(ExpandConstant('{app}\INSTALL.LOG'));

for i := 0 to SvfList.Count-1 do
begin
  str:= SvfList[i];
  DeleteFile(ExpandConstant('{app}\'+str));
end;
если и так не заработает, ну тогда не знаю, что вы там делаете.
 
Последнее редактирование:

Xenium

Новичок
@Xenium,
Cделай удаление по заранее подготовленному логу тогда.
Батник создаст INSTALL.LOG с перечнем файлов без корневого пути. В инно грузишь в stringlist, если есть файл и перебором удаляешь.
Код:
@Echo Off
SetLocal EnableDelayedExpansion
Set DataRoot=%~dp0
Set OutFile=INSTALL.LOG
For /F "delims=" %%A In ('Dir "%DataRoot%\*.*" /B /S /A-D 2^>nul') Do (
  Set str=%%A
  Set stra=!str:%~dp0=!
  Echo !stra!>>"%OutFile%")
Pause
code_language.pascal:
var
  i:integer;
  SvfList: TStringlist;
  str: string;
begin
  SvfList := TStringList.Create;
  SvfList.LoadFromFile(ExpandConstant('{app}\INSTALL.LOG'));

for i := 0 to SvfList.Count-1 do
begin
  str:= SvfList[i];
  DeleteFile(ExpandConstant('{app}\'+str));
end;
если и так не заработает, ну тогда не знаю, что вы там делаете.
Спасибо, так работает)
Но есть еще пара вопросов.
 

sergey3695

Ветеран
Модератор
@Xenium, еще можно добавить в скрипт удаление папок
code_language.pascal:
[UninstallDelete]
Type: dirifempty; Name: "{app}\papka1";
если образуется пустая. как самый простой вариант, прописать вот так.
 

Xenium

Новичок
@sergey3695,
@Xenium, еще можно добавить в скрипт удаление папок
code_language.pascal:
[UninstallDelete]
Type: dirifempty; Name: "{app}\papka1";
если образуется пустая. как самый простой вариант, прописать вот так.
Спасибо, как раз только ночью это сделал)
Но, в моем случае, думаю нужно сделать удаление пустой папки после установки)
 

sergey3695

Ветеран
Модератор
@Xenium,
code_language.pascal:
    RemoveDir(ExpandConstant('{app}\papka1'));
Удаляет папку, если она пустая.
 

Xenium

Новичок
@sergey3695,
@Xenium, скорее всего архив с пустой папкой temp запакован.
Разобрался в чем проблема.
Но пока не соображу как сделать правильно, получается есть каталог с файлом и пустым каталогом
(пример \Gameface(with file)\Content(empty)\Paks(empty) -как в данном случае удалить подкаталоги пустые?
 

Xenium

Новичок
@Xenium,
code_language.pascal:
    RemoveDir(ExpandConstant('{app}\papka1'));
Удаляет папку, если она пустая.
Самое интересное - не хочет работать.
Специально создал пустой каталог, но после удаления он остался, так же как и ветка каталогов из примера выше)
 

sergey3695

Ветеран
Модератор
@Xenium,
code_language.pascal:
[Setup]
AppName = MyApp
AppVerName = MyApp
DefaultDirname = {pf}\MyApp
OutputDir=.

[Code]
var
  List: TStringList;

procedure ScanDir(SearchPath: String);
var
  FindRec: TFindRec;
begin
  if FindFirst(ExpandConstant(AddBackslash(SearchPath)+'*.*'), FindRec) then
  begin
    try
      repeat
        if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then
        begin
          if (FindRec.Name<>'.') and (FindRec.Name<>'..') then
          begin
            List.Add(AddBackslash(SearchPath) + FindRec.Name + '\');
            ScanDir(AddBackslash(SearchPath) + FindRec.Name + '\');
          end;
        end;
      until not FindNext(FindRec);
    finally
      FindClose(FindRec);
    end;
  end;
end;

procedure InitializeWizard;
var
  n: integer;
begin
  List := TStringList.Create;
  ScanDir('E:\Архивы\Новая папка');
  if (List.Count<>0) then
  begin
  for n:= List.Count-1 downto 0 do
    RemoveDir(List[n]);
  end;
end;
 

Xenium

Новичок
@Xenium,
code_language.pascal:
[Setup]
AppName = MyApp
AppVerName = MyApp
DefaultDirname = {pf}\MyApp
OutputDir=.

[Code]
var
  List: TStringList;

procedure ScanDir(SearchPath: String);
var
  FindRec: TFindRec;
begin
  if FindFirst(ExpandConstant(AddBackslash(SearchPath)+'*.*'), FindRec) then
  begin
    try
      repeat
        if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then
        begin
          if (FindRec.Name<>'.') and (FindRec.Name<>'..') then
          begin
            List.Add(AddBackslash(SearchPath) + FindRec.Name + '\');
            ScanDir(AddBackslash(SearchPath) + FindRec.Name + '\');
          end;
        end;
      until not FindNext(FindRec);
    finally
      FindClose(FindRec);
    end;
  end;
end;

procedure InitializeWizard;
var
  n: integer;
begin
  List := TStringList.Create;
  ScanDir('E:\Архивы\Новая папка');
  if (List.Count<>0) then
  begin
  for n:= List.Count-1 downto 0 do
    RemoveDir(List[n]);
  end;
end;
Значит верно я копал)
Вопрос 1 - Он смотрит подкаталоги? (например папка с файлом и в ней есть пустая папка)
Вопрос 2 - Так заменить можно, работать будет? ScanDir('{app}\*');
 

sergey3695

Ветеран
Модератор
@Xenium,
Ответ 1 - да. С самого последнего подкаталога и вверх.
Ответ 2 - так достаточно будет.
ScanDir('{app}');
 

Xenium

Новичок
Кому нужно, вот полный код 2 в 1 (Удаление файлов и пустых папок)
@sergey3695, большое спасибо за Вашу помощь!
Код:
var
  i:integer;
  n: integer;
  SvfList: TStringlist;
  str: string;
begin
  List := TStringList.Create;
  ScanDir(ExpandConstant('{app}\'));
  if (List.Count<>0) then
  begin
  for n:= List.Count-1 downto 0 do
    RemoveDir(List[n]);
    List.Free;
  begin
  SvfList := TStringList.Create;
  SvfList.LoadFromFile(ExpandConstant('{app}\INSTALL.LOG'));
for i := 0 to SvfList.Count-1 do
begin
  str:= SvfList[i];
  DeleteFile(ExpandConstant('{app}\'+str));
  RemoveDir(ExpandConstant('{app}\'));
end;
end;
end;
end;
 

sergey3695

Ветеран
Модератор
@Xenium,
code_language.pascal:
var
  i:integer;
  n: integer;
  SvfList: TStringlist;
begin
// сначала файлы удаляем
  SvfList := TStringList.Create;
  SvfList.LoadFromFile(ExpandConstant('{app}\INSTALL.LOG'));
for i := 0 to SvfList.Count-1 do
  DeleteFile(ExpandConstant('{app}\'+SvfList[i]));
// затем папки чистим
  List := TStringList.Create;
  ScanDir(ExpandConstant('{app}\'));
  if (List.Count<>0) then
  begin
  for n:= List.Count-1 downto 0 do
    RemoveDir(List[n]);
  end;
  List.Free;
end;
 

Xenium

Новичок
@Xenium,
code_language.pascal:
var
  i:integer;
  n: integer;
  SvfList: TStringlist;
begin
// сначала файлы удаляем
  SvfList := TStringList.Create;
  SvfList.LoadFromFile(ExpandConstant('{app}\INSTALL.LOG'));
for i := 0 to SvfList.Count-1 do
  DeleteFile(ExpandConstant('{app}\'+SvfList[i]));
// затем папки чистим
  List := TStringList.Create;
  ScanDir(ExpandConstant('{app}\'));
  if (List.Count<>0) then
  begin
  for n:= List.Count-1 downto 0 do
    RemoveDir(List[n]);
  end;
  List.Free;
end;
:$:good: И снова спасибо)
 

Xenium

Новичок
@sergey3695, столкнулся еще с одним моментом, при удалении, если в папке есть файл с параметром Read Only - он не удаляется.

Подставляю функцию Exec(ExpandConstant('{cmd}'), '/C attrib -R -H "appdir\*.*" /s /d','' , SW_SHOW, ewWaitUntilTerminated, ResultCode); , но если задавать параметр appDir := '{app}'; - она не отрабатывает.
Если задать путь вручную, например E:\Games\MyApp - тогда отрабатывает.

Что я делаю не так?
Код:
var

  i:integer;

  n: integer;

  SvfList: TStringlist;

  appDir: String;

begin

// снимаем атрибуты Скрытый и Только чтение

appDir := '{app}';

Exec(ExpandConstant('{cmd}'), '/C attrib -R -H "appdir\*.*" /s /d','' , SW_SHOW, ewWaitUntilTerminated, ResultCode);

// сначала файлы удаляем

  SvfList := TStringList.Create;

  SvfList.LoadFromFile(ExpandConstant('{app}\INSTALL.LOG'));

for i := 0 to SvfList.Count-1 do

  DeleteFile(ExpandConstant('{app}\'+SvfList[i]));

// затем папки чистим

  List := TStringList.Create;

  ScanDir(ExpandConstant('{app}\'));

  if (List.Count<>0) then

  begin

  for n:= List.Count-1 downto 0 do

    RemoveDir(List[n]);

  end;

  List.Free;

end;
 
Сверху