I have created a small fork of AutoHotkey_L for experimental purposes with several new debugging features. I hope to merge the code back into the main branch after more testing. The REAL AutoHotkey is the Lexikos Version on GitHub.
All my changes are geared around better debugging, troubleshooting and logging support. I'm building a commercial product with this (in fact, I'm building my whole company with it), so I use it all day every day and it's stable for me.
Please report any issues via the GitHub Repository, or the forum thread – or just fork it and fix it ;)
At the moment I only have ANSI builds, but I'll fix the Unicode builds soon (or you are welcome to do so). I also have not updated the documentation yet.
How to Use
It's easy to try this out. The AutoHotkey installer places a backup copy of the original files in your AutoHotkey folder, so it's easy to revert back by simply overwriting a file. If you use the installer, you should find AutoHotkeyA32.exe and AutoHotkeyW32.exe in your AutoHotkey folder. The installer copies one of those files to AutoHotkey.exe based on which option you choose during installation, but you can switch from one to the other by simply overwriting AutoHotkey.exe with the version you want (after closing all scripts), or you can run different scripts with different versions by running the specific executable you want for a particular script.
To test this version, you can save it as AutoHotkey.exe and use it for everything (what I do), or you can save it to a temp file rename it, and then only run it when you want to test my changes. Either way works fine, and you can always revert by simply copying the correct original file to AutoHotkey.exe.
Download the executable from my web site and either overwrite AutoHotkey.exe or save it in a temp folder, rename it and move it into the main AutoHotkey folder. Whether you keep it as AutoHotkey.exe or rename it to something like AutoHotkeyBonzai.exe, it should be in the AutoHotkey folder so script variables like A_AhkPath work as expected.
Stack Trace for All Exceptions
All internal exceptions and those thrown using the Exception object, now include a .StackTrace field that shows the stack trace back to the beginning of execution, similar to .NET or Python. For example, this sample calls a label, which calls a function, which throws an internal exception:
Code: Select all
try {
Gosub RunMe
ExitApp
} catch ex {
CrashException("Uncaught Exception", ex)
}
RunMe:
CDD("\BOGUS")
return
CDD(Folder) {
SetWorkingDir %Folder%
}
Code: Select all
Message: 1
What : SetWorkingDir
File : C:\Temp\TestException.ahk
Line : 16
Stack :
File Line: Context Code
C:\Temp\TestException.ahk 17: CDD() SetWorkingDir %Directory%
C:\Temp\TestException.ahk 12: RunMe: CDD("\BOGUS")
C:\Temp\TestException.ahk 5: RunMe: Gosub,RunMe
- The first two columns are self-explanatory.
- Context is the method or label active at the time of the exception. For example, the last 2 lines are both from the RunMe: label. Labels end in : and functions end in ()
- Code is the first 80 or so characters of the internal AHK version of the code after parsing. It usually matches the code without comments or whitespace. Multi-line statements are concatenated.
At the moment, this only works with internally thrown exceptions and exceptions thrown using the Exception object, so your exceptions you generate yourself in try/catch blocks should look like:
Throw Exception("This is Bogus", -1)
Instead of
Throw "This is bogus"
The format of the Stack Trace is suspiciously similar to compiler errors, and you can pretty easily make most code editors take you right to the line. I've done so for Visual SlickEdit, but not for others. You can probably convert it to any editor format you like with a few lines of AHK code.
Additional Information in Exceptions with A_LastError
For internal commands that set A_LastError (e.g. FileDelete, etc.), a new LastError field is added to the Exception object. This field is formatted as ErrorCode = Error Description where Error Description is obtained from the FormatMessage API call (which is usually but not always right), and ErrorCode is just a copy of A_LastError. If you want to process the numeric part, you can just use A_LastError which will always match the numeric part of the error, or parse the numeric part with a Regex.
For example, if you try to delete a read-only file, it returns an exception object something like:
Code: Select all
Message : 1
What : FileDelete
File : C:\Palabra\AutoHotkey_L\Tests\AhkCompilerTest.ahk
Line : 149
LastError: 5=Access is denied.
Stack :
File Line: Context Code
C:\...\AhkCompilerTest.asx 148: Test_Exception_LastError() FileSetAttrib,+R,%TestFile%
C:\...\UnitTest.ahk 324: TestRunAll() Func(functionName).()
C:\...\AhkCompilerTest.asx 23: RunMe: TestRunAll()
C:\...\AhkBase.ahk 13: RunMe: Gosub,RunMe
Improvements to ListLines
I added several improvements to ListLines because it seldom has enough information to really be useful. This was the first change I made, although now that I've added the stack trace mentioned above I don't use it as much as I once did.
ListLines, File
If you pass a file name as the first parameter to ListLines, the lines are dumped directly to the file and the UI never shows up. You can then open the file and process it any way you like. The command is synchronous, so you can follow it with the command to process the file. If you want to do more detailed preprocessing of the lines, just write the AHK code to scan through the file and make any changes you like. See below for formatting details that are useful for processing the file.
Code: Select all
ListLines, %A_Temp%\ListLines.ahk
You can clear the current line list anytime you like, which is useful after you've loaded up some massive libraries you don't really want in your debug output.
Code: Select all
ListLines, Clear
The new built-in variable A_ListLines returns the current ListLines state. 1=On, 0=Off. You can use it to save/restore the state.
Code: Select all
WasListing := A_ListLines
ListLines, Off
...
ListLines %WasListing%
You can now set ListLines state with True/False in addition to "On"/"Off". This makes it easier to save/restore the state of ListLines.
ListLines Cleanup
I added some features to make the lines easier to read and process.
- Line numbers always have four digits so they line up well for readability.
- The total number of lines that can show up in a file has been increased from 400 to 4000. Note that the original limit of 400 was caused by the ListLines GUI, so the GUI still only shows 400 lines.
- Filenames in the list have a ; at the start. If you list them to a file and open them in an editor with AHK support, they'll show up as comments, which makes them stand out more. Of course the lines themselves are just AHK code so they'll be color coded as well.