I post this here because it seems that this subject is not very well covered, at least in the documentation and from Google results.
Common solutions for logging/debugging are:If you have quite a complex software written in AHK it can be a mess to understand where you script has bugged/crashed.
It can then be usefull to have a variable that contains the last lines executed before the script crashes.
and if you release an ahk software to non computer savy people you might find this log very useful !
-Put debugging messages yourself (like msgbox and tooltip) or manual logging to a text file
-Use a debugger like DebugView with command Outputdebug: https://www.autohotkey.com/docs/command ... tDebug.htm
-Display executed lines by the ListLines command : https://autohotkey.com/docs/commands/ListLines.htm but you need to execute it manually at a certain time and it display a box andis not savable to a variable directly
AND Yes there are some very usefull warning and such but in certain case the information is not very helpful as were the bug is located (for exemple errors in functions handled by windows directly : ex: XML).
In my case:
Having a complex software I write in AHK for almost 2 1/2 year (yes much longer than first expected but a much complexer project as well ... that will hopefully soon be released !!) I'm currently working so that when people encounter a bug they can send me the last executed lines before the crash directly by a simple button in the software.
The solution I am working on and that I will implement will look like :
-Having a function that can save ListLines to a variable
-Making a timer that will save last ~ 100 lines of this variable to a file
-Having two logs files of the current and last session so if the software has crashed last log can be sent and if the program simply failed to do something current log can be sent
-Making a simple GUI / some buttons that will say either 1) I had a serious bug that caused my software to crash ---> It will send last log via email / 2) I have a simple bug --> It will send current log via email
If you are interested by this solution, stay tuned I will try to submit it when I will be finished
If you have suggestions to make they are welcomed even though writing this scheme seems manageable to me so I don't ask for people to loose their time making it themselves
For the script to save LastLines to a variable I found a script by Lexikos (Thanks!) but who made everytime the script (AHK unicode x64 Win7) to crash
https://autohotkey.com/board/topic/5811 ... /?p=365156
So I saw the original post by Lexikos to save ListVars (All vriables and respective value) to a variable, which was maintained and working !
https://autohotkey.com/board/topic/2092 ... /?p=156570
Code: Select all
Loop {
tick := A_TickCount
ToolTip % ListGlobalVars()
}
ListGlobalVars()
{
static hwndEdit, pSFW, pSW, bkpSFW, bkpSW
if !hwndEdit
{
dhw := A_DetectHiddenWindows
DetectHiddenWindows, On
Process, Exist
ControlGet, hwndEdit, Hwnd,, Edit1, ahk_class AutoHotkey ahk_pid %ErrorLevel%
DetectHiddenWindows, %dhw%
astr := A_IsUnicode ? "astr":"str"
ptr := A_PtrSize=8 ? "ptr":"uint"
hmod := DllCall("GetModuleHandle", "str", "user32.dll", ptr)
pSFW := DllCall("GetProcAddress", ptr, hmod, astr, "SetForegroundWindow", ptr)
pSW := DllCall("GetProcAddress", ptr, hmod, astr, "ShowWindow", ptr)
DllCall("VirtualProtect", ptr, pSFW, ptr, 8, "uint", 0x40, "uint*", 0)
DllCall("VirtualProtect", ptr, pSW, ptr, 8, "uint", 0x40, "uint*", 0)
bkpSFW := NumGet(pSFW+0, 0, "int64")
bkpSW := NumGet(pSW+0, 0, "int64")
}
if (A_PtrSize=8) {
NumPut(0x0000C300000001B8, pSFW+0, 0, "int64") ; return TRUE
NumPut(0x0000C300000001B8, pSW+0, 0, "int64") ; return TRUE
} else {
NumPut(0x0004C200000001B8, pSFW+0, 0, "int64") ; return TRUE
NumPut(0x0008C200000001B8, pSW+0, 0, "int64") ; return TRUE
}
ListVars
NumPut(bkpSFW, pSFW+0, 0, "int64")
NumPut(bkpSW, pSW+0, 0, "int64")
ControlGetText, text,, ahk_id %hwndEdit%
RegExMatch(text, "sm)(?<=^Global Variables \(alphabetical\)`r`n-{50}`r`n).*", text)
return text
}
Code: Select all
;By Lexikos
Loop {
tick := A_TickCount
ToolTip % ListLines()
}
ListLines()
{
static hwndEdit, pSFW, pSW, bkpSFW, bkpSW
ListLines Off
if !hwndEdit
{
dhw := A_DetectHiddenWindows
DetectHiddenWindows, On
Process, Exist
ControlGet, hwndEdit, Hwnd,, Edit1, ahk_class AutoHotkey ahk_pid %ErrorLevel%
DetectHiddenWindows, %dhw%
astr := A_IsUnicode ? "astr":"str"
ptr := A_PtrSize=8 ? "ptr":"uint"
hmod := DllCall("GetModuleHandle", "str", "user32.dll", ptr)
pSFW := DllCall("GetProcAddress", ptr, hmod, astr, "SetForegroundWindow", ptr)
pSW := DllCall("GetProcAddress", ptr, hmod, astr, "ShowWindow", ptr)
DllCall("VirtualProtect", ptr, pSFW, ptr, 8, "uint", 0x40, "uint*", 0)
DllCall("VirtualProtect", ptr, pSW, ptr, 8, "uint", 0x40, "uint*", 0)
bkpSFW := NumGet(pSFW+0, 0, "int64")
bkpSW := NumGet(pSW+0, 0, "int64")
}
if (A_PtrSize=8) {
NumPut(0x0000C300000001B8, pSFW+0, 0, "int64") ; return TRUE
NumPut(0x0000C300000001B8, pSW+0, 0, "int64") ; return TRUE
} else {
NumPut(0x0004C200000001B8, pSFW+0, 0, "int64") ; return TRUE
NumPut(0x0008C200000001B8, pSW+0, 0, "int64") ; return TRUE
}
ListLines
NumPut(bkpSFW, pSFW+0, 0, "int64")
NumPut(bkpSW, pSW+0, 0, "int64")
ControlGetText, ListLinesText,, ahk_id %hwndEdit%
RegExMatch(ListLinesText, ".*`r`n`r`n\K[\s\S]*(?=`r`n`r`n.*$)", ListLinesText)
StringReplace, ListLinesText, ListLinesText, `r`n, `n, All
ListLines On
return ListLinesText ; This line appears in ListLines if we're called more than once.
}
I will post on advancements soon