I recently had a similar problem. This was my solution to detect if a text file (profile) has been changed from the one installed during the last installation run:
Use ISPP (Inno Setup Pre-Processor) to create the list of text files and their hashes at compile time:
[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
At the top of the "Code" section I define some useful things:
[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;
In the "Check" event handler I compare the hashes of previous install and current file:
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;
In the "AfterInstall" event handler I mark the file hash to be stored in
Registry later. Because in my tests the event was triggered even if the file move failed (target file is read-only) I compare the hash again to find out if the file move was successful:
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;
UninsNeverUninstallflag and then add a[CODE]section forCurUninstallStepChangedusPostUninstallwhere all TXT files would checked for CRC and then deleted if CRC equal or if CRC not equal user would be informed about changed files + asked if files should be deleted. - RobeN