Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

How to check if 2 files are same?

202 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 AM5/29/24
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

Martin Ba

unread,
Jul 18, 2024, 4:17:02 AM7/18/24
to innosetup
Regarding Powershell:

Be extremely wary of calling anything powershell in a loop. (Or in this case maybe: For each file or somesuch.)
Powershell has a very, very significant startup cost: Depending on you system we are talking seconds to start up a powershell process. (Always use -NoProfile)
Even best case we are talking 100-200ms to just start up powershell.exe (or pwsh.exe) (compared to low 10ms with cmd.exe)

This is totally fine when you have a powershell script that does a bunch of things and you call it once or twice.
We had to learn the hard way that this makes runtime explode if you call a powershell script from cmd or Inno 100s of times.

/MB
Reply all
Reply to author
Forward
0 new messages