Inno设置-在更新时删除旧的/过时的文件



所以,我意识到这个问题以前也被问过。事实上,在写这篇文章之前,我已经通读了其中的10篇,但没有一篇有适用的解决方案,我希望现在有人找到了一些东西。

问题是:我的程序是用一个脚本构建的,在一个文件夹中创建所有最终文件。这些文件包含在inno中,如下所示:

[Files]
Source: "buildexe.win-amd64-3.6*"; Excludes: "*.key, *.log"; DestDir: "{app}"; 
Flags: ignoreversion recursesubdirs createallsubdirs

该应用程序已经发布了几个月,并进行了不同的更新。不再有旧文件的记录,尽管它可能会被重新组装,因为我们确实有版本控制,我可以再次构建旧的安装程序。

据我所知,您应该使用InstallDelete部分来清除旧文件,但您不应该使用通配符,也没有Excludes部分来保护我们拥有的可能包含他们想要保留的用户数据的单个文件夹。

那么,我该如何处理旧文件呢?该应用程序是100 MB,当前用户可能有300 MB以上的旧文件不再需要,我很乐意清理这些文件。

TL;DR:我希望安装程序覆盖或删除应用程序目录中的所有文件,但包含用户数据的文件夹除外。

最简单的解决方案是在安装之前删除安装文件夹中的所有文件。

正如您所知,您可以使用[InstallDelete]部分来实现这一点。但这不允许您排除"数据"文件夹。

您可以改为编写Pascal Scripting。请参见Inno Setup-删除除数据子目录外的整个应用程序文件夹。你可以根据我对CurStepChanged(ssInstall)事件函数的问题的回答调用DelTreeExceptSavesDir函数:

procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then
begin
DelTreeExceptSavesDir(WizardDirValue); 
end;
end;

如果您真的只想删除过时的文件,为了避免删除和重新创建现有文件(不是您的情况,因为您无论如何都在使用ignoreversion标志),您可以使用预处理器生成要为Pascal脚本安装的文件列表,并使用该列表只删除真正过时的文件。

#pragma parseroption -p-
#define FileEntry(DestDir) 
"  FilesNotToBeDeleted.Add('" + LowerCase(DestDir) + "');n"
#define ProcessFile(Source, Dest, FindResult, FindHandle) 
FindResult 
? 
Local[0] = FindGetFileName(FindHandle), 
Local[1] = Source + "\" + Local[0], 
Local[2] = Dest + "\" + Local[0], 
(Local[0] != "." && Local[0] != ".." 
? FileEntry(Local[2]) + 
(DirExists(Local[1]) ? ProcessFolder(Local[1], Local[2]) : "") 
: "") + 
ProcessFile(Source, Dest, FindNext(FindHandle), FindHandle) 
: 
""
#define ProcessFolder(Source, Dest) 
Local[0] = FindFirst(Source + "\*", faAnyFile), 
ProcessFile(Source, Dest, Local[0], Local[0])
#pragma parseroption -p+
[Code]
var
FilesNotToBeDeleted: TStringList;
function InitializeSetup(): Boolean;
begin
FilesNotToBeDeleted := TStringList.Create;
FilesNotToBeDeleted.Add('data');
{#Trim(ProcessFolder('buildexe.win-amd64-3.6', ''))}
FilesNotToBeDeleted.Sorted := True;
Result := True;
end;
procedure DeleteObsoleteFiles(Path: string; RelativePath: string);
var
FindRec: TFindRec;
FilePath: string;
FileRelativePath: string;
begin
if FindFirst(Path + '*', FindRec) then
begin
try
repeat
if (FindRec.Name <> '.') and (FindRec.Name <> '..') then
begin
FilePath := Path + '' + FindRec.Name;
FileRelativePath := RelativePath + '' + FindRec.Name;
if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then
begin
DeleteObsoleteFiles(FilePath, FileRelativePath);
end;
if FilesNotToBeDeleted.IndexOf(Lowercase(FileRelativePath)) < 0 then
begin
if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then
begin
if RemoveDir(FilePath) then
begin
Log(Format('Deleted obsolete directory %s', [FilePath]));
end
else
begin
Log(Format('Failed to delete obsolete directory %s', [FilePath]));
end;
end
else
begin
if DeleteFile(FilePath) then
begin
Log(Format('Deleted obsolete file %s', [FilePath]));
end
else
begin
Log(Format('Failed to delete obsolete file %s', [FilePath]));
end;
end;
end;
end;
until not FindNext(FindRec);
finally
FindClose(FindRec);
end;
end
else
begin
Log(Format('Failed to list %s', [Path]));
end;
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then
begin
Log('Looking for obsolete files...');
DeleteObsoleteFiles(WizardDirValue, '');
end;
end;

有关其他选项,请参阅Inno设置:删除以前版本安装的文件。

最新更新