How to check if 2 files are same?

168 views
Skip to first unread message

Xiong Mar

unread,
Nov 15, 2023, 9:45:38 PM11/15/23
to innosetup
I want to check if the existing file in destination folder is same as a file reside in setup bundle, and then decide to copy different files.

Bill Stewart

unread,
Nov 20, 2023, 2:15:36 PM11/20/23
to innosetup
On Wednesday, November 15, 2023 at 7:45:38 PM UTC-7 Xiong Mar wrote:

I want to check if the existing file in destination folder is same as a file reside in setup bundle, and then decide to copy different files.

This is not trivial but can be done. For an example, see the posed answer on the following StackOverflow question:



Xiong Mar

unread,
Nov 28, 2023, 3:41:22 AM11/28/23
to innosetup
The work is done. The code is as follows:
===============iss code================
  function IsDefineSpoSame(file1: string; file2: string): Boolean;
  external 'IsDefineSpoSame@files:pbdata.dll stdcall setuponly';
....
   Profession := False;
    if FileExists(WizardDirValue() + ExpandConstant('\{#MyInstallFlagFile}')) then begin
      ExtractTemporaryFile('{#MyProfessionFlagFile}');
      if FileExists(ExpandConstant('{tmp}\{#MyProfessionFlagFile}')) then
      begin
        Profession := IsDefineSpoSame(WizardDirValue() + ExpandConstant('\{#MyInstallFlagFile}'), ExpandConstant('{tmp}\{#MyProfessionFlagFile}'));
        DeleteFile(ExpandConstant('{tmp}\{#MyProfessionFlagFile}'));
      end
    end;

===============c code================
#define BUFFERSIZE_DEFINE_SPO 30
extern "C" BOOL APIENTRY IsDefineSpoSame(const wchar_t* file1, const wchar_t* file2)
{
BOOL result = FALSE;
FILE *stream1, *stream2;
unsigned char buff1[BUFFERSIZE_DEFINE_SPO + 1], buff2[BUFFERSIZE_DEFINE_SPO + 1], *p;
size_t numread1, numread2, compareCount, offset;

if ((stream1 = _wfsopen(file1, L"rb", _SH_DENYWR)) != NULL) {
if ((stream2 = _wfsopen(file2, L"rb", _SH_DENYWR)) != NULL)
{
numread1 = fread_s(buff1, BUFFERSIZE_DEFINE_SPO, 1, BUFFERSIZE_DEFINE_SPO, stream1);
compareCount = numread2 = fread_s(buff2, BUFFERSIZE_DEFINE_SPO, 1, BUFFERSIZE_DEFINE_SPO, stream2);
// do real work
if (numread1 != numread2) {
if (numread1 < numread2) {
p = buff2 + numread1;
compareCount = numread1;
offset = numread2 - numread1;
}
else {
p = buff1 + numread2;
compareCount = numread2;
offset = numread1 - numread2;
}
for (size_t i = 0; i < offset; ++i) {
if (p[i] != '\xd' && p[i] != '\xa') {
goto IsDefineSpoSameOut1;
}
}
}
result = 0 == memcmp(buff1, buff2, compareCount);
IsDefineSpoSameOut1:
fclose(stream2);
}
fclose(stream1);
}
return result;
}

Bill Stewart

unread,
Nov 28, 2023, 2:54:03 PM11/28/23
to innosetup
On Tuesday, November 28, 2023 at 1:41:22 AM UTC-7 Xiong Mar wrote:

The work is done. The code is as follows:

I don't recommend this approach (very inefficient to extract the files just for comparing).

See the answer I posted on StackOverflow for a better way.

Message has been deleted

Laurent Combémorel

unread,
May 29, 2024, 8:12:14 AMMay 29
to innosetup
Hi
You can call a PowerShell command to get the SHA256 checksum of the existing file, to compare with the SHA256 checksum (that you should compute and store as a constant in your code) of the file you put in your package. If the checksums are different, the files are different. No need to extract the file and compare line by line!
The PowerShell command is:
get-filehash "PATH\FILENAME" -Algorithm sha256 | Select-Object -ExpandProperty Hash

Reply all
Reply to author
Forward
0 new messages