Old 29th May 2012, 14:57   #1
Junior Member
Join Date: Dec 2011
Posts: 13
Exclamation FileFunc:GetTime - strange behavior

Hello, I wrote a few simple "do not delete if file was modified" macroes today and testing em now (those are quite simple and more like template atm, but they do work),
but there is a problem with seconds return value, in FileFunc::GetTime.
Can someone please test the following code or explain the strange behavior of GetTime in FileFunc.nsh?


!include LogicLib.nsh
!include FileFunc.nsh
!insertmacro GetTime
!insertmacro un.GetTime

!macro AddUninstInfo fullPath fileName
;считать UTC время в переменные
${GetTime} ${fullPath} "MS" $0 $1 $2 $3 $4 $5 $6
;записать в INI
WriteINIStr "$INSTDIR\uninstInfo.ini" ${fileName} "day" $0
WriteINIStr "$INSTDIR\uninstInfo.ini" ${fileName} "month" $1
WriteINIStr "$INSTDIR\uninstInfo.ini" ${fileName} "year" $2
;WriteINIStr "$INSTDIR\uninstInfo.ini" ${fileName} "weekday" $3
WriteINIStr "$INSTDIR\uninstInfo.ini" ${fileName} "hour" $4
WriteINIStr "$INSTDIR\uninstInfo.ini" ${fileName} "minute" $5
WriteINIStr "$INSTDIR\uninstInfo.ini" ${fileName} "second" $6

var iniDay
var iniMonth
var iniYear
var iniHour
var iniMinute
var iniSecond ;here - seconds returned are (almost) always differ by one second, so
var iniSecondMin ;here is a workaround
var iniSecondMax ;
!macro UnmodifiedDelete fullPath fileName
;считать UTC время в переменные
${un.GetTime} ${fullPath} "MS" $0 $1 $2 $3 $4 $5 $6
;считать данные из INI по файлу
ReadINIStr $iniDay "$INSTDIR\uninstInfo.ini" ${fileName} "day"
ReadINIStr $iniMonth "$INSTDIR\uninstInfo.ini" ${fileName} "month"
ReadINIStr $iniYear "$INSTDIR\uninstInfo.ini" ${fileName} "year"
ReadINIStr $iniHour "$INSTDIR\uninstInfo.ini" ${fileName} "hour"
ReadINIStr $iniMinute "$INSTDIR\uninstInfo.ini" ${fileName} "minute"
ReadINIStr $iniSecond "$INSTDIR\uninstInfo.ini" ${fileName} "second"
IntOp $iniSecondMin $6 - 3
IntOp $iniSecondMax $6 + 3
MessageBox MB_OK "$0=$iniDay $1=$iniMonth $2=$iniYear $3 $4=$iniHour $5=$iniMinute $6=$iniSecond, $iniSecondMin, $iniSecondMax"
;сравнить данные
${If} $0 == $iniDay
${AndIf} $1 == $iniMonth
${AndIf} $2 == $iniYear
${AndIf} $4 == $iniHour
${AndIf} $5 == $iniMinute
${AndIf} $6 > $iniSecondMin
${AndIf} $6 < $iniSecondMax
;Delete ${fullPath}
MessageBox MB_OK "${fullPath} unmodified - should be deleted"

What it does - writes datetime info into an ini file (that is formed in $INSTDIR) about every installed file (filenames as a tag atm.).
Then, when time X comes, uninstaller can read that info for a file in question, and delete it only if there was no modifications done to it.

install section:
File "$%SOME_ROOT%\release\bin\file1.dll"
;add after File
!insertmacro AddUninstInfo "$%SOME_ROOT%\release\bin\file1.dll" "file1.dll"

uninstall section:
;instead of Delete
!insertmacro UnmodifiedDelete "$INSTDIR\bin\file1.dll" "file1.dll"

On my PC and notebook $6 almost always is wrong. For example if file properties say mod. time is 10:15:42, the seconds part returned by GetTime equals 43... Is it my PC or?..
BreezeUADN is offline   Reply With Quote
Old 29th May 2012, 15:13   #2
Senior Member
Join Date: Mar 2006
Location: Dallas
Posts: 462
I'm slightly confused by the file location in "fullpath", but I think I can explain the problem. The FAT file system uses a 2 second resolution when the time is stored, and zip and NSIS files do the same. NTFS maintains file times with much greater resolution (100 nsec).

If you are comparing the original time of a file on your build system (NTFS) against a file extracted from NSIS program (FAT style) and stored on a target machine, you must allow for the seconds to be truncated (rounded) to the 2 second precision.

Perhaps you can eliminate the time comparison and use md5 hash values? Uninstall files that have unchanged hash values, keep files with new hash values.
demiller9 is offline   Reply With Quote
Old 30th May 2012, 06:52   #3
Junior Member
Join Date: Dec 2011
Posts: 13
Thank you demiller9, you were completely right about NTFS<->FAT32, so hash is a better idea.
(and ye sorry about fullpath - not the right name for that parameter. Also copy-paste is evil and there have to be
!insertmacro AddUninstInfo "$INSTDIR\bin\file1.dll" "file1.dll"
instead of
!insertmacro AddUninstInfo "$%SOME_ROOT%\release\bin\file1.dll" "file1.dll"
BreezeUADN is offline   Reply With Quote
Go Back   Winamp & SHOUTcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump