Inno setup InnoSetup:don';t卸载已更改的文件

Inno setup InnoSetup:don';t卸载已更改的文件,inno-setup,Inno Setup,如何告诉InnoSetup不要卸载用户更改的(文本)文件(=与InnoSetup安装的文件不同) 或者可能更难:在现有的基础上安装新版本时,InnoSetup应该询问用户是否覆盖更改的文件,但在纯卸载时,它应该在没有询问的情况下卸载该文件。Inno无法以本机方式执行此检查 要在安装过程中不替换更改的文件,您需要使用自定义的[code]进行校验和,并与先前安装中预计算或保存的已知良好值进行比较 为了避免在卸载过程中删除它们,您需要禁用Inno自己对该文件的卸载,并在删除它们之前检查相同的校验和,同

如何告诉InnoSetup不要卸载用户更改的(文本)文件(=与InnoSetup安装的文件不同)


或者可能更难:在现有的基础上安装新版本时,InnoSetup应该询问用户是否覆盖更改的文件,但在纯卸载时,它应该在没有询问的情况下卸载该文件。

Inno无法以本机方式执行此检查

要在安装过程中不替换更改的文件,您需要使用自定义的
[code]
进行校验和,并与先前安装中预计算或保存的已知良好值进行比较

为了避免在卸载过程中删除它们,您需要禁用Inno自己对该文件的卸载,并在删除它们之前检查相同的校验和,同样在
[code]


请注意,最好将用户可以编辑的任何文件保留在安装程序之外,以便更好地处理这种情况并正确遵守应用程序指南。

我最近遇到了类似的问题。这是我的解决方案,用于检测文本文件(配置文件)是否已从上次安装运行期间安装的文本文件(配置文件)更改:

使用ISPP(Inno Setup Pre Processor)在编译时创建文本文件及其哈希列表:

[Files]
; ...
#define FindHandle
#define FindResult
#define Mask "Profiles\*.ini"
#sub ProcessFoundFile
   #define FileName "Profiles\" + FindGetFileName(FindHandle)
   #define FileMd5 GetMd5OfFile(FileName)
   Source: {#FileName}; DestDir: {app}\Profiles; Components: profiles; \
      Check: ProfileCheck('{#FileMd5}'); AfterInstall: ProfileAfterInstall('{#FileMd5}');
#endsub
#for {FindHandle = FindResult = FindFirst(Mask, 0); FindResult; FindResult = FindNext(FindHandle)} ProcessFoundFile
在“代码”部分的顶部,我定义了一些有用的东西:

[Code]
var
   PreviousDataCache : tStringList;

function InitializeSetup() : boolean;
begin
   // Initialize global variable
   PreviousDataCache := tStringList.Create();
   result := TRUE;
end;

function BoolToStr( Value : boolean ) : string;
begin
   if ( not Value ) then
      result := 'false'
   else
      result := 'true';
end;
在“Check”事件处理程序中,我比较了先前安装和当前文件的哈希值:

function ProfileCheck( FileMd5 : string ) : boolean;
var
   TargetFileName, TargetFileMd5, PreviousFileMd5 : string;
   r : integer;
begin
   result := FALSE;
   TargetFileName := ExpandConstant(CurrentFileName());
   Log('Running check procedure for file: ' + TargetFileName);

   if not FileExists(TargetFileName) then
   begin
      Log('Check result: Target file does not exist yet.');
      result := TRUE;
      exit;
   end;

   try
      TargetFileMd5 := GetMd5OfFile(TargetFileName);
   except
      TargetFileMd5 := '(error)';
   end;
   if ( CompareText(TargetFileMd5, FileMd5) = 0 ) then
   begin
      Log('Check result: Target matches file from setup.');
      result := TRUE;
      exit;
   end;

   PreviousFileMd5 := GetPreviousData(ExtractFileName(TargetFileName), '');
   if ( PreviousFileMd5 = '' ) then
   begin
      r := MsgBox(TargetFileName + #10#10 + 
         'The existing file is different from the one Setup is trying to install. ' + 
         'It is recommended that you keep the existing file.' + #10#10 +
         'Do you want to keep the existing file?', mbConfirmation, MB_YESNO);
      result := (r = idNo);
      Log('Check result: ' + BoolToStr(result));
   end
   else if ( CompareText(PreviousFileMd5, TargetFileMd5) <> 0 ) then
   begin
      r := MsgBox(TargetFileName + #10#10 + 
         'The existing file has been modified since the last run of Setup. ' +
         'It is recommended that you keep the existing file.' + #10#10 +
         'Do you want to keep the existing file?', mbConfirmation, MB_YESNO);
      result := (r = idNo);
      Log('Check result: ' + BoolToStr(result));
   end
   else
   begin
      Log('Check result: Existing target has no local modifications.');
      result := TRUE;
   end;
end;

也许您可以使用
uninseneveruninstall
标志,然后添加
[code]
部分为
CurUninstallStepChanged
usPostUninstall
检查所有TXT文件是否存在CRC,然后在CRC相等或CRC不相等的情况下删除。将通知用户更改的文件并询问是否应删除文件。这些文件是什么?如果是配置文件,最好安装一个具有不同名称的默认文件,如果主配置文件不存在,则将其复制到主配置文件的位置。如果它们是用户文件,则安装程序不应触摸它们。您的问题中有两个问题。卸载和安装是不同的步骤。请允许我询问您何时调用RegisterPreviousData()?@JulienM:
RegisterPreviousData
是Inno安装程序在存在同名函数时自动调用的事件函数。有关更多信息,请参阅Inno安装帮助。做得好;如果能在InnoSetup中添加一个与此等效的标志,那就太好了!
procedure ProfileAfterInstall( FileMd5 : string );
var
   TargetFileName, TargetFileMd5 : string;
begin
   TargetFileName := ExpandConstant(CurrentFileName());
   try
      TargetFileMd5 := GetMd5OfFile(TargetFileName);
   except
      TargetFileMd5 := '(error)';
   end;
   if ( CompareText(TargetFileMd5, FileMd5) = 0 ) then
   begin
      Log('Storing hash of installed file: ' + TargetFileName);
      PreviousDataCache.Add(ExtractFileName(TargetFileName) + '=' + FileMd5);
   end;
end;

procedure RegisterPreviousData( PreviousDataKey : integer );
var
   Name, Value : string;
   i, n : integer;
begin
   for i := 0 to PreviousDataCache.Count-1 do
   begin
      Value := PreviousDataCache.Strings[i];
      n := Pos('=', Value);
      if ( n > 0 ) then
      begin
         Name := Copy(Value, 1, n-1);
         Value := Copy(Value, n+1, MaxInt);
         SetPreviousData(PreviousDataKey, Name, Value);
      end;
   end;
end;