Page 1 of 1

Request: A_AhkBuildDate

Posted: 13 Mar 2020, 19:14
by Raccoon
Request for the variable A_AhkBuildDate to compliment A_AhkVersion
Returns a human readable date when Autohotkey was built.

Also include this date in the Main Window titlebar, next to the version number.

Re: Request: A_AhkBuildDate

Posted: 14 Mar 2020, 16:13
by Delta Pythagorean
I don't quite see a use for this, mind elaborating what this could benefit?

Re: Request: A_AhkBuildDate

Posted: 14 Mar 2020, 17:00
by HotKeyIt
You can modify Ahk2Exe to add a line on top of any compiled script: global A_AhkBuildDate="20200314"

Re: Request: A_AhkBuildDate

Posted: 15 Mar 2020, 19:28
by Raccoon
I should have elaborated. I want to know the date that A_AhkVersion was compiled (and uploaded to the Autohotkey website), from within my scripts. That is, I want to know old AutoHotkey v1.1.32.00 is. The Build Date of the AutoHotkey Software.

Re: Request: A_AhkBuildDate

Posted: 16 Mar 2020, 02:36
by HotKeyIt
Probably:

Code: Select all

MsgBox % A_AhkBuildDate("1.1.32.00")
A_AhkBuildDate(build){
  whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  whr.Open("GET", "https://github.com/Lexikos/AutoHotkey_L/releases/tag/v" build, true)
  whr.Send()
  whr.WaitForResponse()
  if RegExMatch(whr.ResponseText,"m)relative-time datetime=""([^""]+)""",builddate)
    Return SubStr(builddate1,1,10)
  else return 0
}

Re: Request: A_AhkBuildDate

Posted: 18 Mar 2020, 05:14
by Raccoon
Does that work without an internet connection?

Re: Request: A_AhkBuildDate

Posted: 18 Mar 2020, 05:18
by swagfag
it does not

Re: Request: A_AhkBuildDate

Posted: 22 Apr 2020, 11:42
by SKAN

Code: Select all

MsgBox % PEDT(A_AhkPath)

PEDT(PEfile) { ; returns build date for Exe/Dll files                                  
Local File, DT:=1970 
  File := FileOpen(PEfile,"r")
  If ! IsObject(File)
      Return
  If ( File.ReadUSHORT()<>0x5A4D )                 ; Is IMAGE_DOS_HEADER.e_magic = 'MZ'?
      Return File.Close() + ""
  File.Seek(60,0)                                  ; Seek IMAGE_DOS_HEADER.e_lfanew 
  File.Seek(File.ReadUINT(),0)                     ; Seek IMAGE_NT_HEADERS
  If ( File.ReadUINT()<>0x00004550 )               ; Is IMAGE_NT_HEADERS.Signature = 'PE'?
      Return File.Close() + ""
  File.Seek(4,1)                                   ; Seek IMAGE_FILE_HEADER.TimeDateStamp
  DT += File.ReadUINT(), S                         ; 
  File.Close()
Return DT
}

Re: Request: A_AhkBuildDate

Posted: 07 Sep 2020, 04:01
by Raccoon
@SKAN thanks! :o

Re: Request: A_AhkBuildDate

Posted: 07 Sep 2020, 13:31
by Drugwash
Alternatively, or in conjunction with SKAN's solution above there may be another one that reads LastWrite time for the selected file. It may be of use, say to check if the file has been tampered with. As long as the file is in its original pristine state the LastWrite timestamp should be the same as the linker timestamp in the PE header.

The following is an AHK adaptation of the example code found here. Note that the original example uses the safe API StringCchPrintf() but for the life of me I couldn't get it to work here so I used the older "unsafe" version.

The date/time format of the output string can be changed by modifying the format string (second parameter of sprintf) and/or the order of the arguments following it (and the size of the r buffer if necessary). Currently it is in European format: day.month.year-full hour:minutes:seconds .

Disclaimer: I only tested it with AHK 32bit executable, in WINE under Linux Mint. There may be structure misalignment with 64bit AHK.

Code: Select all

MsgBox % GLMT(A_AhkPath)

GLMT(p)
{
VarSetCapacity(r, 40, 32)		; 19 Unicode chars + NULL
VarSetCapacity(buf, 36, 0)		; WIN32_FILE_ATTRIBUTE_DATA struct
VarSetCapacity(tu, 16, 0)		; SYSTEMTIME struct
if !DllCall("GetFileAttributesEx", "Str", p, "UInt", 0, "Ptr", &buf)
	return "Error 1"
if !DllCall("FileTimeToSystemTime", "Ptr", &buf+20, "Ptr", &tu)
	return "Error 2"
if !DllCall("msvcrt\sprintf"
	, "AStr", r
	, "AStr", "%02d.%02d.%04d %02d:%02d:%02d"
	, "UShort", NumGet(tu, 6, "UShort")	; day
	, "UShort", NumGet(tu, 2, "UShort")	; month
	, "UShort", NumGet(tu, 0, "UShort")	; year
	, "UShort", NumGet(tu, 8, "UShort")	; hour
	, "UShort", NumGet(tu, 10, "UShort")	; minutes
	, "UShort", NumGet(tu, 12, "UShort")	; seconds
	, "CDecl")
	return "Error 3"
return r
}