Archive: GetFileTime vs GetFileTimeLocal yields different results


GetFileTime vs GetFileTimeLocal yields different results
If I do a GetFileTimeLocal on a file, install it, then do a GetFileTime on that same file it gives different results. The timezones on the build computer and the computer i am installing on are the same. Can anyone help?

Code:

  GetFileTime ${destfile} $R0 $R1 ; File it will be replacing
GetFileTimeLocal ${localfile} $R2 $R3 ; File to install
DetailPrint "Existing File=${destfile}"
DetailPrint "Existing File=$R0.$R1"
DetailPrint "New File=${localfile}"
DetailPrint "New File=$R2.$R3"
IntCmp $R0 $R2 0 "installlibbydate.start_${INSTALLLIBBYDATE_UNIQUE}" "installlibbydate.done_${INSTALLLIBBYDATE_UNIQUE}"
IntCmp $R1 $R3 "installlibbydate.done_${INSTALLLIBBYDATE_UNIQUE}" "installlibbydate.start_${INSTALLLIBBYDATE_UNIQUE}" "installlibbydate.done_${INSTALLLIBBYDATE_UNIQUE}"


Results:
Existing File=C:\Documents and Settings\XPMUser\Desktop\NSIS Testing\AspenAI.dll
Existing File=30188312.338555648
New File=C:\Development\Aspen2000\bin\AspenAI.dll
New File=30188312.356245648

From MSDN:

Not all file systems can record creation and last access times and not all file systems record them in the same manner. For example, on FAT, create time has a resolution of 10 milliseconds, write time has a resolution of 2 seconds, and access time has a resolution of 1 day (really, the access date). Therefore, the GetFileTime function may not return the same file time information set using the SetFileTime function.
I'm guessing this is the issue, so you should probably add a fuzz factor of about 4 seconds. Or you could try calling CompareFileTime() with the system plugin, but I'm not sure if it does any fuzzing...

The getfiletime/getfiletimelocal commands are ok, the problem starts in makensis: the compiler truncates file times to a 2 second resolution. I think this is so the 'ifnewer' attribute will succeed when extracting to FAT volumes.


Thanks. Both posts are very helpful. I'll try to figure out how to either truncate the file time to a 2 second resolution or add a fuzz factor of 4 seconds or so. I've been having some difficulty finding documentation on doing this so if anyone knows how to do this your help would be appreciated.


It might be a bug if makensis fuzzes the time and the exehead does not


Thanks for the help. I think I got this working. Let me know if you see anything wrong.


!macro ConvertFileTimeToInt64 out high low
System::Int64Op ${high} * 4294967296
Pop ${out}
System::Int64Op ${out} + ${low}
Pop ${out}
System::Int64Op ${out} / 10000000
Pop ${out}
!macroend

...

GetFileTime ${destfile} $R0 $R1 ; File it will be replacing
!insertmacro ConvertFileTimeToInt64 $R2 $R0 $R1
GetFileTimeLocal ${localfile} $R0 $R1 ; File to install
!insertmacro ConvertFileTimeToInt64 $R3 $R0 $R1
System::Int64Op $R3 - $R2
Pop $R4
DetailPrint "Existing File=${destfile}"
DetailPrint "Existing File=$R0"
; DetailPrint "New File=${localfile}"
DetailPrint "New File.....=$R2"
DetailPrint "Difference...=$R3"
IntCmp $R4 4 "installlibbydate.skip_${INSTALLLIBBYDATE_UNIQUE}" "installlibbydate.skip_${INSTALLLIBBYDATE_UNIQUE}" "installlibbydate.start_${INSTALLLIBBYDATE_UNIQUE}"

Why are you not using "SetOverwrite ifnewer" and letting NSIS take care of it for you? (There is a bug here also but it will be fixed when we figure out what to do about it)


These are COM DLL's that need to be unregistered if it is determined that the file is newer. We will only use this method for DLL's that our company writes. We can't go based on the DLL version because it doesn't always change between builds.