- NSIS Discussion
- Understanding GetFileTime
Archive: Understanding GetFileTime
n0On3
30th October 2002 01:41 UTC
Understanding GetFileTime
I am trying to work with this function. I read, using the search, that we have to compare resulting variables with IntCmpU (Unsigned), but testing with GetFileTime I see that sometimes it returns negative numbers.
Another thing, how can I get the minutes and seconds from that number? I want that to calculate elapsed time, but it can be useful to calculate current date/time if compared with a file of known date (then we don't have to use a dll:))
n0On3
30th October 2002 15:53 UTC
Thanks kichik, that was one of the threads I read before posting.:)
I still don't understand "I use IntCmpU because a DWORD is an unsigned long" because, as I say in my first post, sometimes GetFileTime returns a signed number. Does sounds to me as a contradiction.
kichik
30th October 2002 15:56 UTC
You see it as a signed number because that's how you look at it. Both signed and unsigned numbers are saved as bits of 0 or 1, and the sign depends on how you treat them. If you look at them as signed numbers they will have a sign, if you don't they won't.
n0On3
30th October 2002 16:12 UTC
So, the good way to look at those numbers is as unsigned, ok. But I didn't decide which way I look at those numbers, I just made a DetailPrint.
The other question: Is there a way I can pull seconds and minutes from that number?
Thanks for being so patient
:)
kichik
30th October 2002 16:23 UTC
It's not the good way, it's THE way ;)
You will have to use brainsucker's System.dll to do this calculation. The FILETIME (which is used to get these two numbers) structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC). I am sorry but I am pretty busy right now so I won't be able to help you with the script... Maybe brainsucker will be able to help you, he know his DLL better than I do anyway :D
brainsucker
31st October 2002 11:28 UTC
I've included such example into just posted release (Sample 6). See examples/system.nsi.
n0On3
1st November 2002 17:20 UTC
Originally posted by kichik
is a 64-bit value representing the number of 100-nanosecond intervals
So, I can divide for 10^7 and get seconds, isn't it?
brainsucker
2nd November 2002 02:20 UTC
hm... there will be a little problem, since GetFileTime return this time as two DWORDS, time=DW1*4294967296+DW2... So you have to do a little calculations.
n0On3
2nd November 2002 02:34 UTC
some calculations? just a substraction, or two because we have two dwords.
Anyway it's better this than have to work with a dll.
Are there any plans to add GetCurrentTime function to nsis? Otherwise a function can be made for this.
brainsucker
2nd November 2002 13:51 UTC
Two substractions, one multiplication and one addition. ;)
Yes you are right, it's easier... if you are planning to use that for delta-times (differences between two times).
Afrow UK
1st March 2003 13:59 UTC
So what is the actual script for converting GetFileTime high and low dwords into readable hours and minutes?
eg. x:xx
This script should be written down on the NSIS archive.
-Stuart
n0On3
1st March 2003 21:08 UTC
Originally posted by Afrow UK
So what is the actual script for converting GetFileTime high and low dwords into readable hours and minutes?
eg. x:xx
This script should be written down on the NSIS archive.
-Stuart
Well, it's more or less in the archive :p The title is "report elapsed time at the end" or something like this.
Anyway, to get seconds from that double number (as I said before) you only need to divide by 10000000.
If you still need the code here it is:
GetTempFileName $R5
GetFileTime $R5 $R6 $R7
IntOp $R7 $R7/ 10000000
>
This three lines are copied and pasted from that script :eek:
deguix
1st March 2003 21:33 UTC
This code don't work rightly if pass some minutes (if you for example add a hour to Windows Clock before the detection of the install end time with the example "report elapsed time at the end")...
Afrow UK
1st March 2003 21:37 UTC
I attempted to use that before, but it was screwing up and giving me minus times.
I have just used the plugin instead...
http://myweb.tiscali.co.uk/imker/afr...ads/nsisdt.zip
This plugin dll allows you to enter like 15 different combinations of dates and/or times into your app.
Special thanks to Rainwater for writing the plugin :)
-Stuart
deguix
1st March 2003 22:23 UTC
But I beleave that have a bug in this NSISdt:
oct/28 until feb/08 - show -1 hour (i.e. 01/01/2003 00:30 show 31/12/2002 23:30 !).
mar/7 until oct/20 - show +1 hour (i.e. 04/30/2003 23:30 show 05/01/2003 00:30 !).
I've sended a PM to the rainwater and he read, but not replied my message until now.
deguix
2nd March 2003 07:17 UTC
? 31/12/2002? Whoops, is 12/31/2002.
oct/28 -> feb/08 - show -1 hour (i.e. 01/01/2003 00:30 show 12/31/2002 23:30 !).
mar/7 -> oct/20 - show +1 hour (i.e. 04/30/2003 23:30 show 05/01/2003 00:30 !).
kichik
2nd March 2003 16:58 UTC
I believe that's because the function called in NSISdt is taking the day light saving time into consideration. I don't see anything wrong with that.
deguix
2nd March 2003 17:25 UTC
-1 or +1 hour of original time. In my computer for example the clock is showing now 14:29, now the NSISdt show normal (we are between feb/8 and mar/7), but after mar/7 will show +1 hour of original time (the time here will not to be in the summer time!), after oct/20 will show the original time, and after oct/28 will show -1 hour (when the time here will be in the summer time). Now it's more explained, isn't it?
deguix
2nd March 2003 19:57 UTC
And a question, how I can use the "systemGetFileSysTime demo" in the System.nsi? Ever when I use this in a script, give me a error:
"This program run an ilegal operation and will be close"
Output "C:\Test.exe"
>Caption "Test"
>!include "${NSISDIR}\\Contrib\\System\\sysfunc.nsh"
>Section
!insertmacro smGetFileSysTime $CMDLINE
System
::Call '*$R0${stSYSTEMTIME}(.r1, .r2, .r3, .r4, .r5, .r6, .r7, .r8)'
MessageBox MB_OK "GetFileSysTime example: file '$CMDLINE', year $1, month $2, dow $3, day $4, hour $5, min $6, sec $7, ms $8"
; free memory from SYSTEMTIME
System::Free $R0
SectionEnd
>
brainsucker
3rd March 2003 23:28 UTC
Hm... I see no reasons for "This program run an ilegal operation and will be close" message here. :)
In fact I've found a small bug in this code example - $CMDLINE may return for installer.exe name in double quotes, or with some parameters, so I've changed scripts a bit (Could Kichik or some one else update CVS version please ;). See bellow for script which works fine for me at win98/xp (you should first update sysfunc.nsh from attached zip). Reply if you'll have more problems, please.
Name "System Plugin Example"
>OutFile "date.exe"
>SetPluginUnload alwaysoff
>!include "${NSISDIR}\Contrib\System\sysfunc.nsh"
>Section "ThisNameIsIgnoredSoWhyBother?"
SetOutPath $TEMP
; ----- Sample 6 ----- systemGetFileSysTime demo -----
Call GetInstallerExeName
pop $0
!insertmacro smGetFileSysTime $0
System
::Call '*$R0${stSYSTEMTIME}(.r1, .r2, .r3, .r4, .r5, .r6, .r7, .r8)'
MessageBox MB_OK "GetFileSysTime example: file '$0', year $1, month $2, dow $3, day $4, hour $5, min $6, sec $7, ms $8"
; last plugin call must not have /NOUNLOAD so NSIS will be able to delete the temporary DLL
SetPluginUnload manual
; free memory from SYSTEMTIME
System::Free $R0
SectionEnd
>
kichik
4th March 2003 16:31 UTC
Done.
deguix
5th March 2003 06:38 UTC
After downloading these new files, I've tested this example and didn't show any error messages, but the result of all values (year, month, day of week...) are 0:
GetFileSysTime example: file 'C:\path\date.exe', year 0, month 0, dow 0, day 0, hour 0, min 0, sec 0, ms 0
And I've detected a new bug with another example in System.nsi:
Show a blue screen after another when I execute the compiled example 1 - Message box with custom icon, here is the script:
Name "System Plugin Example 1"
>OutFile "CustomMessageBox.exe"
>SetPluginUnload alwaysoff
>!include "${NSISDIR}\\Contrib\\System\\sysfunc.nsh"
>Section "ThisNameIsIgnoredSoWhyBother?"
SetOutPath $TEMP
; ----- Sample 1 ----- Message box with custom icon -----
!
insertmacro smMessageBox "i 0" "Message box with custom icon!" "System Example 1a" ${MB_OK} "i 103"
; i 0 - installer exe as module
; i 103 - icon ID
; The same example but using icon from resource.dll.
;You could use this dll for storing your resources, just replace FAR icon
; with something you really need.
File "${NSISDIR}\\Contrib\\System\\Resource.dll"
!insertmacro smMessageBox "`$TEMP\\resource.dll`" "Message box with custom icon from resource.dll!" "System Example 1b" ${MB_OK} "i 103"
Delete $TEMPresource.dll
SectionEnd
>
brainsucker
5th March 2003 14:11 UTC
Could you report, please, which windows version you are using?
System.nsi shows blue screen too? If so could you please cut and test smaller samples from it (like 3, 4 and 5). If they'll run ok, then it will be best to find exact place giving blue screen (by cutting and testing separate actions from 1 sample (system::calls at systemMessageBox proc at sysfunc.nsh)). If not.... hm...
getfiletime could return zero values when it couldn't find the file. Again - see no reasons. Could you please insert after the call to sysFindFirstFile (at sysfunc) the next line:
MessageBox MB_OK "$1 $2 $3"
and post here the message box text.
deguix
6th March 2003 07:43 UTC
Could you report, please, which windows version you are using?
Windows 98 Second Edition
System.nsi shows blue screen too? If so could you please cut and test smaller samples from it (like 3, 4 and 5). If they'll run ok, then it will be best to find exact place giving blue screen (by cutting and testing separate actions from 1 sample (system::calls at systemMessageBox proc at sysfunc.nsh)). If not.... hm...
Now I cannot do this now (Connected to Internet, if gives the blue screen now the connection will be lost), but tomorrow I will report at here. Only that I know now, it occours when it try to insert the icon in the messagebox, after this show two blue screens ,show a message that the system is warningly lack of resources, and make a loop with the blue screens and this message.
getfiletime could return zero values when it couldn't find the file. Again - see no reasons. Could you please insert after the call to sysFindFirstFile (at sysfunc) the next line:
MessageBox MB_OK "$1 $2 $3"
and post here the message box text.
Show:
:) Nothing! :)
deguix
7th March 2003 08:20 UTC
I had track for bugs at this morning on the example 1, and saw on what line that occours this error, there is the line:
System::Call '${sysFreeLibrary}(r1)'
The line "IntCmp $2 0 0 smbskipfree smbskipfree" ever continue to this line above, because the line
"System::Call '${sysGetModuleHandle}($2) .r1'" don't return the handle, because the line
"System::Call '${sysLoadLibrary}($2) .r1'" don't load the module.
In the first !insertmacro line of the file that contain the "System Plugin Example 1" (not System.nsi),
the module that is pushed to stack is "i 0", return this value at line "System::Call '${sysLoadLibrary}($2) .r1'"
(file SysFunc.nsh), return this value at "System::Call '${sysGetModuleHandle}($2) .r1'" (file SysFunc.nsh),
continue in the line "IntCmp $1 0 0 smbnext smbnext" (file SysFunc.nsh) and go at the problem line
"System::Call '${sysGetModuleHandle}($2) .r1'" (file SysFunc.nsh), after this show blue screens after another.