Jump to content
zorphnog

log4a - A logging UDF

Recommended Posts

zorphnog

I routinely need to log information for my scripts. In the past, I've usually just created functions in each script to write to a log file. I also use ConsoleWrite in conjunction with SciTE a lot when I'm trying to debug scripts. After using some logging libraries for other languages (namely NLog (C#) and Java (log4j)) I decided to write a logging UDF for AutoIt. I decided to base it loosely upon the log4j and NLog libaries. I say loosely because this one is not nearly as feature rich as either one of those, but I think it still provides a nice logging interface.

What can it do?

  • Output types: Console, File, or Both. Additionally, you can configure the logger to output differently based on whether the script is compiled or not. This way you can output to the console (SciTE) while you're writing a script, and output to a log file when you've compile the script.
  • Log levels: While I don't think it's really necessary to have this many log levels, these are the levels in ascending order of severity:
    • Trace
    • Debug
    • Info
    • Warn
    • Error
    • Fatal
  • Log Filtering: The log can be enabled and disabled. There are also minimum and maximum log levels that can be configured to only show a range of log levels (i.e. a minimum level of warn would not log messages for trace, debug, or info). These filter levels can be overridden when logging a message if the need be.
  • Error Stream: Logging can be configured to write to the stderr (i.e. ConsoleWriteError). When enabled, any log messages at the error level and above will be written to the error stream.
  • Message Format Macros: The logging message format can be customized to your liking using the following macros:
    • ${date} = Long date (i.e. MM/DD/YYYY HH:MM:SS)
    • ${host} = Hostname of local machine
    • ${level} = The current log level
    • ${message} = The log message
    • ${newline} = Insert a newline
    • ${shortdate} = Short date (i.e. MM/DD/YYYY)

 

Available Functions:

  • Configuration Functions
    • _log4a_SetCompiledOutput - Sets the logging output type for the compiled version of the script (Default: $LOG4A_OUTPUT_FILE)
    • _log4a_SetEnable - Enables or disables logging messages (Default: Disabled)
    • _log4a_SetErrorStream - Enables or disables logging of the standard error stream (Default: Enabled)
    • _log4a_SetFormat - Configures the format of logging messages (Default: "${date} ${level} ${message}")
    • _log4a_SetLogFile - Sets the path of the log file (Default: "<ScriptFullPath>.log")
    • _log4a_SetMaxLevel - Configures the maximum log level to process messages (Default: $LOG4A_LEVEL_FATAL)
    • _log4a_SetMinLevel - Configures the minimum log level to process messages (Default: $LOG4A_LEVEL_TRACE)
    • _log4a_SetOutput - Sets the logging output type for the non-compiled version of the script (Default: $LOG4A_OUTPUT_CONSOLE)
  • Logging Functions
    • _log4a_Debug - Logs a message at the debug level
    • _log4a_Error - Logs a message at the error level
    • _log4a_Fatal - Logs a message at the fatal level
    • _log4a_Info - Logs a message at the info level
    • _log4a_Message - Logs a message to the configured outputs
    • _log4a_Trace - Logs a message at the trace level
    • _log4a_Warn - Logs a message at the warn level

See the source file for full documentation of available functions.

 

A quick example script:

#include "log4a.au3"

; Enable logging and don't write to stderr
_log4a_SetEnable()
_log4a_SetErrorStream(False)
log_messages()

; Write to stderr, set min level to warn, customize message format
_log4a_SetErrorStream()
_log4a_SetMinLevel($LOG4A_LEVEL_INFO)
If @compiled Then _log4a_SetMinLevel($LOG4A_LEVEL_WARN) ; Change the min level if the script is compiled
_log4a_SetFormat("${shortdate} | ${host} | ${level} | ${message}")
log_messages()

; Disable logging (except for those that override)
_log4a_SetEnable(False)
log_messages()

Func log_messages()
  _log4a_Trace("A TRACE message", True) ; overrides filters
  _log4a_Debug("A DEBUG message")
  _log4a_Info("A INFO message")
  _log4a_Warn("A WARN message")
  _log4a_Error("A ERROR message", True) ; overrides filters
  _log4a_Fatal("A FATAL message")
EndFunc

 
 
Without further adieu, the UDF:
log4a.au3

Edited by zorphnog
  • Like 3

Share this post


Link to post
Share on other sites
Amundo

Sorry to necropost, but this is awesome!

Thanks very much for this!

Share this post


Link to post
Share on other sites
mmoalem

ok so completely nubee here and wondered if I can use this to generate a log of all the commands in my script as they are executed? I have a script that runs on a server 24/7 and i want to know, in case the server crash, where was the script interupted...

Share this post


Link to post
Share on other sites
mLipok

@zorphnog

Nice UDF.

Question: Whether you can implement this concept:

 

to your UDF ?

 


Signature beginning:   Wondering who uses AutoIT and what it can be used for ?
* GHAPI UDF - modest begining - comunication with GitHub REST API *
ADO.au3 UDF     POP3.au3 UDF     XML.au3 UDF    How to use IE.au3  UDF with  AutoIt v3.3.14.x  for other useful stuff click the following button

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API *

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF *

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * 

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2018-03-17

Share this post


Link to post
Share on other sites
dubi
"D:\...Multi_ToFileV003_stripped.au3"(1753,73) : warning: $__aLog4aLevels: possibly used before declaration.
Local $sLine = __log4a_FormatMessage($sMessage, $__aLog4aLevels[$eLevel])
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"D:\...Multi_ToFileV003_stripped.au3"(1753,73) : error: $__aLog4aLevels: undeclared global variable.
Local $sLine = __log4a_FormatMessage($sMessage, $__aLog4aLevels[$eLevel])
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

Apologies that I have to pull this older topic up again...
I wanted to uses this UDF and I am getting an error when compiling my script (which is necessary). In the UDF $__aLog4aLevels is declared as const but when searching it in the stripped version of my file I cannot find the const-definition there either. Is this an Autoit Version issue? How can I overcome this?

Needless to say that I have included the UDF into my include-list...

Thank you

 

Share this post


Link to post
Share on other sites
BrewManNH

That variable is declared in line 35 of the posted UDF as an array.

 

It seems that the stripped file might be missing it, the function got rearranged after stripping, or some other weirdness happened.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites
dubi

good hint - thank you. I have added the declaration manually into the stripped file and compiled this and ... see - it works. Weired indeed...

Thank you

Share this post


Link to post
Share on other sites
vick

Hi,

 

How i can use this UDF in my automation script so if script fails i can open log file and check where it went wrong pls?

thanks,

Share this post


Link to post
Share on other sites
JLogan3o13

@vick we operate on the "teach a man to fish" motto in this forum, rather than spoon-feeding you code. What have you tried on your own? Have you downloaded the UDF and had a go at the different functions? What isn't working for you? Help us help you.


√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites
vick

Hi,

I have downloaded this UDF and put in include folder and added it in script. but my question is do i have to create any function for log again in script ?

i am looking for simple example where in script it is used to get log so i can do it same in my script and verify it.

 

thanks,

Share this post


Link to post
Share on other sites
Earthshine

You are AWESOME!! Thanks SO MUCH for the logger! Works wonderful! I use this for everything and it has been so successful as I have been trying to build an automation software test tool set to test our applications! This has been a lifesaver, and, when instrumented with proper logging, you really don't need a debugger.

 

Thank the original poster of this thread SO MUCH!!

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Share this post


Link to post
Share on other sites
n3wbie

Can Someone Provide Some More Examples Where in there are actual Errors In Script and I can Get Output

I tried example script given above

My Basic Doubt is do i need to Call Logmessages() again and again in script?

or if i just once write it it will start logging

M unable to understand Script or its level above my understanding level

Share this post


Link to post
Share on other sites
Earthshine
Posted (edited)

you have to add the debug, trace, etc.. type of messages you want where you want them in the code. I log lots of things.

First, in your main script, include the log4a.au3 file and configure the logging for your application or main script like so: that way it will log to console if run under editor, or log to a .log file when compiled.

#include "log4a.au3"

#Region ;**** Logging ****
; Enable logging and don't write to stderr
_log4a_SetEnable()
; Write to stderr, set min level to warn, customize message format
_log4a_SetErrorStream()
_log4a_SetMinLevel($LOG4A_LEVEL_TRACE)
If @compiled Then _log4a_SetMinLevel($LOG4A_LEVEL_WARN) ; Change the min level if the script is compiled
_log4a_SetFormat("${date} | ${host} | ${level} | ${message}")
#EndRegion ;**** Logging ****

Then you can do stuff like this in other modules

#include-once
#include <Timers.au3>
#include "log4a.au3"


; #FUNCTION# ====================================================================================================================
; Name ..........: _waitControlClick
; Description ...: Automatically wait for a control to exist. Forever or Limited
; Syntax ........: _waitControlClick($formclass, $text, $ctrl, $ctrltxt, $timeout, $delayafter
; Parameters ....: $formclass           - Form Class info.
;                  $text                - Windows Forms text to match
;                  $ctrl                - Class of Copntrol
;                  $ctrltxt             - Text of the Control you search for
;                  $timeout             - [Optional] Timeout, Default = 0, millisecond timer
;                  $delayafter          - [Optional] Time to delay after operation carried out
; Return values .: None
; Author ........: Earthshine
; Modified ......:
; Remarks .......:  Waits for each button indefinatly.
;                   Logger found here: https://www.autoitscript.com/forum/topic/156196-log4a-a-logging-udf/
; Related .......:
; Link ..........:
; Example(s) ....:  _waitControlClick ('[CLASS:#32770]', 'ApplicationX - InstallShield Wizard', '[CLASS:Button; INSTANCE:1]', , '&Next >' 5000, 0)
;                   _waitControlClick($formclass, $text, $button2, $TD_BTN_REMOVE, 0, 0)
;                   _waitControlClick($formclass, $text, $button3, $TD_BTN_NEXT, 0, 500)
;                   _waitControlClick($formclass, $text, $button1, $TD_BTN_YES, 0, 0)
;                   _waitControlClick($formclass, $text, $button4, $TD_BTN_FINISH, 0, 0)
; ===============================================================================================================================
Func _waitControlClick($formclass, $text, $ctrl, $ctrltxt, $timeout = 0, $delayafter = 0)
    _log4a_Info("_waitControlClick():Begin")
    _log4a_Info("Searching for Formclass: " & $formclass)
    _log4a_Info("Searching for Text: " & $text)
    _log4a_Info("Searching for Control: " & $ctrl)
    _log4a_Info("Searching for Ctrl Txt: " & $ctrltxt)
    _log4a_Info("Timeout: " & $timeout)
    _log4a_Info("Time Delay (after click): " & $delayafter)
    Local $time_run = _Timer_Init()
    While (1)
        If WinExists($formclass) Then
            Local $hCtrl = ControlGetHandle($text, '', $ctrl)
            If $hCtrl Then
                If ($timeout > 0) Then
                    _log4a_Info(_Timer_Diff($time_run))
                    If (_Timer_Diff($time_run) > $timeout) Then
                        _log4a_Info("ExitLoop:Timeout - " & $ctrl)
                        ExitLoop
                    EndIf
                EndIf
                Local $hCtrlHandle = ControlGetText($text, '', $ctrl)
                _log4a_Info("Control Text Search: " & $ctrltxt)
                _log4a_Info("Control Text Found: " & $hCtrlHandle)
                If ($hCtrlHandle == $ctrltxt) Then
                    ; we got the handle, so the button is there
                    ; now do whatever you need to do
                    _log4a_Info("Found Formclass: " & $formclass)
                    _log4a_Info("Found Text: " & $text)
                    _log4a_Info("Found Control: " & $ctrl)
                    _log4a_Info("Found Ctrl Txt: " & $ctrltxt)
                    _log4a_Info("Timeout: " & $timeout)
                    _log4a_Info("Time Delay (after click): " & $delayafter)
                    _log4a_Info('Control ' & $ctrl & ' Clicked')
                    ControlClick($formclass, '', $ctrl)
                    If ($delayafter > 0) Then
                        Sleep($delayafter)
                    EndIf
                    _log4a_Info("ExitLoop:Normal - " & $ctrl)
                    ExitLoop
                EndIf
            EndIf
        EndIf
    WEnd
    _log4a_Info("_waitControlClick():End")
EndFunc   ;==>_waitControlClick

Here is the sample script listed above, using each type of message and how you log it. The log_messages() function is only a crude example to show you the different ways you can configure the logger. Notice you call that little function to show you the log settings you are configuring. You are just supposed to use the methods provided by the UDF to log your Warnings, Errors, Information or Fatal types

#include "log4a.au3"

; Enable logging and don't write to stderr
_log4a_SetEnable()
_log4a_SetErrorStream(False)
log_messages()

; Write to stderr, set min level to warn, customize message format
_log4a_SetErrorStream()
_log4a_SetMinLevel($LOG4A_LEVEL_INFO)
If @compiled Then _log4a_SetMinLevel($LOG4A_LEVEL_WARN) ; Change the min level if the script is compiled
_log4a_SetFormat("${shortdate} | ${host} | ${level} | ${message}")
log_messages()

; Disable logging (except for those that override)
_log4a_SetEnable(False)
log_messages()

Func log_messages()
  _log4a_Trace("A TRACE message", True) ; overrides filters
  _log4a_Debug("A DEBUG message")
  _log4a_Info("A INFO message")
  _log4a_Warn("A WARN message")
  _log4a_Error("A ERROR message", True) ; overrides filters
  _log4a_Fatal("A FATAL message")
EndFunc
Quote

first call to log_messages()

05\22\2018 09:36:08 Debug A DEBUG message
05\22\2018 09:36:08 Info A INFO message
05\22\2018 09:36:08 Warning A WARN message
05\22\2018 09:36:08 Error A ERROR message
05\22\2018 09:36:08 Fatal A FATAL message

2nd call to log_messages() configured to display messages in style below


05\22\2018 | BUILD1 | Trace | A TRACE message
05\22\2018 | BUILD1 | Info | A INFO message
05\22\2018 | BUILD1 | Warning | A WARN message
05\22\2018 | BUILD1 | Error | A ERROR message
05\22\2018 | BUILD1 | Fatal | A FATAL message

3rd call produces this due to configured settings. notice only these two get through due to the third and last config option in the test above


05\22\2018 | BUILD1 | Trace | A TRACE message
05\22\2018 | BUILD1 | Error | A ERROR message
 

 

Edited by Earthshine
  • Like 1

My resources are limited. You must ask the right questions

 

Share this post


Link to post
Share on other sites
n3wbie
19 hours ago, Earthshine said:

you have to add the debug, trace, etc.. type of messages you want where you want them in the code. I log lots of things.

First, in your main script, include the log4a.au3 file and configure the logging for your application or main script like so: that way it will log to console if run under editor, or log to a .log file when compiled.

#include "log4a.au3"

#Region ;**** Logging ****
; Enable logging and don't write to stderr
_log4a_SetEnable()
; Write to stderr, set min level to warn, customize message format
_log4a_SetErrorStream()
_log4a_SetMinLevel($LOG4A_LEVEL_TRACE)
If @compiled Then _log4a_SetMinLevel($LOG4A_LEVEL_WARN) ; Change the min level if the script is compiled
_log4a_SetFormat("${date} | ${host} | ${level} | ${message}")
#EndRegion ;**** Logging ****

Then you can do stuff like this in other modules

#include-once
#include <Timers.au3>
#include "log4a.au3"


; #FUNCTION# ====================================================================================================================
; Name ..........: _waitControlClick
; Description ...: Automatically wait for a control to exist. Forever or Limited
; Syntax ........: _waitControlClick($formclass, $text, $ctrl, $ctrltxt, $timeout, $delayafter
; Parameters ....: $formclass           - Form Class info.
;                  $text                - Windows Forms text to match
;                  $ctrl                - Class of Copntrol
;                  $ctrltxt             - Text of the Control you search for
;                  $timeout             - [Optional] Timeout, Default = 0, millisecond timer
;                  $delayafter          - [Optional] Time to delay after operation carried out
; Return values .: None
; Author ........: Earthshine
; Modified ......:
; Remarks .......:  Waits for each button indefinatly.
;                   Logger found here: https://www.autoitscript.com/forum/topic/156196-log4a-a-logging-udf/
; Related .......:
; Link ..........:
; Example(s) ....:  _waitControlClick ('[CLASS:#32770]', 'ApplicationX - InstallShield Wizard', '[CLASS:Button; INSTANCE:1]', , '&Next >' 5000, 0)
;                   _waitControlClick($formclass, $text, $button2, $TD_BTN_REMOVE, 0, 0)
;                   _waitControlClick($formclass, $text, $button3, $TD_BTN_NEXT, 0, 500)
;                   _waitControlClick($formclass, $text, $button1, $TD_BTN_YES, 0, 0)
;                   _waitControlClick($formclass, $text, $button4, $TD_BTN_FINISH, 0, 0)
; ===============================================================================================================================
Func _waitControlClick($formclass, $text, $ctrl, $ctrltxt, $timeout = 0, $delayafter = 0)
    _log4a_Info("_waitControlClick():Begin")
    _log4a_Info("Searching for Formclass: " & $formclass)
    _log4a_Info("Searching for Text: " & $text)
    _log4a_Info("Searching for Control: " & $ctrl)
    _log4a_Info("Searching for Ctrl Txt: " & $ctrltxt)
    _log4a_Info("Timeout: " & $timeout)
    _log4a_Info("Time Delay (after click): " & $delayafter)
    Local $time_run = _Timer_Init()
    While (1)
        If WinExists($formclass) Then
            Local $hCtrl = ControlGetHandle($text, '', $ctrl)
            If $hCtrl Then
                If ($timeout > 0) Then
                    _log4a_Info(_Timer_Diff($time_run))
                    If (_Timer_Diff($time_run) > $timeout) Then
                        _log4a_Info("ExitLoop:Timeout - " & $ctrl)
                        ExitLoop
                    EndIf
                EndIf
                Local $hCtrlHandle = ControlGetText($text, '', $ctrl)
                _log4a_Info("Control Text Search: " & $ctrltxt)
                _log4a_Info("Control Text Found: " & $hCtrlHandle)
                If ($hCtrlHandle == $ctrltxt) Then
                    ; we got the handle, so the button is there
                    ; now do whatever you need to do
                    _log4a_Info("Found Formclass: " & $formclass)
                    _log4a_Info("Found Text: " & $text)
                    _log4a_Info("Found Control: " & $ctrl)
                    _log4a_Info("Found Ctrl Txt: " & $ctrltxt)
                    _log4a_Info("Timeout: " & $timeout)
                    _log4a_Info("Time Delay (after click): " & $delayafter)
                    _log4a_Info('Control ' & $ctrl & ' Clicked')
                    ControlClick($formclass, '', $ctrl)
                    If ($delayafter > 0) Then
                        Sleep($delayafter)
                    EndIf
                    _log4a_Info("ExitLoop:Normal - " & $ctrl)
                    ExitLoop
                EndIf
            EndIf
        EndIf
    WEnd
    _log4a_Info("_waitControlClick():End")
EndFunc   ;==>_waitControlClick

Here is the sample script listed above, using each type of message and how you log it. The log_messages() function is only a crude example to show you the different ways you can configure the logger. Notice you call that little function to show you the log settings you are configuring. You are just supposed to use the methods provided by the UDF to log your Warnings, Errors, Information or Fatal types

#include "log4a.au3"

; Enable logging and don't write to stderr
_log4a_SetEnable()
_log4a_SetErrorStream(False)
log_messages()

; Write to stderr, set min level to warn, customize message format
_log4a_SetErrorStream()
_log4a_SetMinLevel($LOG4A_LEVEL_INFO)
If @compiled Then _log4a_SetMinLevel($LOG4A_LEVEL_WARN) ; Change the min level if the script is compiled
_log4a_SetFormat("${shortdate} | ${host} | ${level} | ${message}")
log_messages()

; Disable logging (except for those that override)
_log4a_SetEnable(False)
log_messages()

Func log_messages()
  _log4a_Trace("A TRACE message", True) ; overrides filters
  _log4a_Debug("A DEBUG message")
  _log4a_Info("A INFO message")
  _log4a_Warn("A WARN message")
  _log4a_Error("A ERROR message", True) ; overrides filters
  _log4a_Fatal("A FATAL message")
EndFunc

 

On the Point what i was confused for

Thanks For This example Will Use It!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • c.haslam
      By c.haslam
      cDebug.au3 includes four main debugging UDFs: _GuiDebug(), _ConsDebug(), _ClipDebug() and _FormatValsForDebug(). They all dump the values of all AutoIt subtypes and expressions, in a structured manner, including nested arrays (up to 3 dimensions) and slices of them, and even DLL structs and maps. It is an alternative to a graphical debugger, offering GUI output.
      The format for calling the UDFs has been designed to make coding a call as convenient and fast as possible, minimizing coding effort and the chances of errors: the $name argument is often the same as the variables arguments, enclosed in quote marks.
      For DLL structures, if you specify a tag, cDebug checks for differences between it and what it detects. If you only specify a structure variable, it can report the structure it detects, with the values of elements.
      It does much more than MsgBox(), ConsoleWrite() and _ArrayDisplay(), in a definitely user-friendly manner, and does its best to avoid hiding your code in SciTE.
      #include cDebug no maps.au3 or cDebug.au3 at the top of your script. If you #include cDebug.au3 (the version with maps)  #include #AutoIt3Wrapper_Version=B before #include cDebug.au3
      It is fully documented in cDebug.pdf   .  During debugging and development of new features, the current version is used to debug the upcoming version, so there is much testing, even so  bugs are always possible, particularly in new features, such as reporting elements of maps whose keys match a regular expression. Bug reports and suggestions are welcome.
      These UDFs have been in regular use for some years.
      Because when cDebug was developed, maps were a use at your own risk feature, there are two streams of cDebug:
      cDebug.au3 reports maps, so to use it you must be running a version of AutoIt that supports maps, e.g. 3.3.15.0, and #include cDebug.au3 cDebug no maps.au3 does not report maps, so you can be running any recent version of AutoIt, e.g. 3.3.14.5, and #include cDebug no maps.au3 The only difference between the two streams is that map-reporting code is commented out in cDebug no maps.au3 .
      A teaser
      This script:
      #AutoIt3Wrapper_Version=B ; beta 3.3.15.0 or greater is mandatory for cDebug.au3 #include "cDebug.au3" Local $seasons[] $seasons.summer = 'May to September' $seasons.spring = 'April' $seasons.fall = 'October to November' $seasons.winter = 'December to March' Local $aCats[3][3] = [['jack','black',3],['suki','grey',4],[$seasons,'','']] Local $i = 1 Local $tStruct = DllStructCreate('uint') DllStructSetData($tStruct,1,2018) _GuiDebug('At line '&@ScriptLineNumber,'$cats,jack is,$cats[..][$i],$i,hex,structure{uint}', _ $aCats,$aCats[0][2],$aCats,$i,Hex(-$i),$tstruct) produces:

       
      Edit history
      See documentation PDF
      Acknowledgements
      Melba23, Kafu, ProgAndy, jchd
    • valdemar1977
      By valdemar1977
      Dbug is graphical debugger for AutoIt.
      Project started by @Heron in 2009 and now supported by @asdf8 and @valdemar1977.
      Features
      Debug the complete script or just parts of it Display run status (line number of currently executed function) GUI default always-on-top in the upper right corner for comfortable debugging WM_NOTIFY and WM_COMMAND hook to prevent interference with possible message handlers Display scope, type and value of variables, expressions, macro's and constants (global AND function local) Execute commands in an immediate window. Can be expressions, functions and assignments Detailed display of array, struct and object variables Dynamic display of variable value in the source code (under cursor) Array table viewer with ability to view the sub-arrays, the correct handling of macro @Error, @Extended and other changes OEM and ANSI console output Conditional breakpoints Saving settings and debugging state and much more... How to use
      Extract from downloaded archive _Dbug.au3 to your Autoit include dir Add #include <_Dbug.au3> in to your code and run code Before compile or buid comment or remove #include <_Dbug.au3> from your code
    • c.haslam
      By c.haslam
      cDebug.au3 includes four main debugging UDFs: _GuiDebug(), _ConsDebug(), _ClipDebug() and _FormatValsForDebug(). They all dump the values of all AutoIt subtypes and expressions, in a structured manner, including nested arrays and slices of them, and even DLL structs and maps. It is an alternative to a graphical debugger, offering GUI output.
      The format for calling the UDFs has been designed to make coding a call as convenient and fast as possible, minimizing coding effort and the chances of errors: the $name argument is often the same as the variables arguments, enclosed in quote marks.
      For DLL structures, if you specify a tag, cDebug checks for differences between it and what it detects. If you only specify a structure variable, it can report the structure it detects, with the values of elements.
      It does much more than MsgBox(), ConsoleWrite() and _ArrayDisplay(), in a definitely user-friendly manner, and does its best to avoid hiding your code in SciTE.
      It is fully documented.  During development of new features, the current version is used to debug the upcoming version, so there is much testing.
      These UDFs have been in regular use for some years. Suggestions and bug reports are most welcome.
      Get the latest version in Example Scripts
      #AutoIt3Wrapper_Version=B ; beta 3.3.15.0 or greater is mandatory for cDebug.au3, not for cDebug no maps.au3 #include "cDebug.au3" Local $seasons[] $seasons.summer = 'May to September' $seasons.spring = 'April' $seasons.fall = 'October to November' $seasons.winter = 'December to March' Local $aCats[3][3] = [['jack','black',3],['suki','grey',4],[$seasons,'','']] Local $i = 1 Local $tStruct = DllStructCreate('uint') DllStructSetData($tStruct,1,2018) _GuiDebug('At line '&@ScriptLineNumber,'$cats,jack is,$cats[..][$i],$i,hex,structure{uint}', _ $aCats,$aCats[0][2],$aCats,$i,Hex(-$i),$tstruct) reports

         
    • Kevin Finnegan
      By Kevin Finnegan
      Hi all,
      Long time lurker and now forum poster! I'm writing a relatively simple backup script for my firm that automates the copy, compression and organization of Leaver's data on one of our secured NAS systems. I personally found the best method to do this so far was to use 7zG.exe (GUI version of 7Zip which can use command-line too) and it functions quite well!
      I would like to retrieve more info on whether any warnings or errors happen in 7Zip during the backup, but I can't quite get my head around the syntax and switches for reading out, it seems any adjustment I make to the RunWait call's string seems to break the backup or give unexpected repercussions! Hopefully its something silly I'm doing as I don't code very often.
      Here is the working version:
      ; Compress the directories one by one in the zip using the listfile.... Local $iPID = RunWait(@ScriptDir & "\bin\7zG.exe a -mx" & $compressionQuality & " -v" & $compressSplitFileSize & " -wc:\temp " _ & $backupToLocation & "\" & $userDirectory & ".7z @bin\listfile.txt -x@bin\excludefile.txt", "", @SW_SHOWDEFAULT, $STDOUT_CHILD) Ultimately I would love to switch entirely to 7za.exe (standalone) so that I can read the progress percentage, current file being uploaded and any warnings or errors could be processed and output to the AutoIT script's GUI I've created rather than jumping in and out of two applications per se.
       
    • RC86
      By RC86
      Hi all,
      Bit of a fun one with querying WMI objects and setting errors within a function.  Below is example code that I've used from JSThePatriot previous UDFs but the example would apply to many other scenarios.  Basically the SetError should be called if $colItems is not an object as a result of the WMI query.  This is then used to create a corresponding error message.
      I've tried disabling WMIC thus forcing it to not be an object, but rather than catching the error and telling me about it, the code simply fails therefore surely making the purpose of the logging useless??  I've experienced this before but in other languages such as java i would use a try catch etc and get around this....any suggestions for its use in AutoIT?

      Thanks
       
       
      #region Header #comments-start Title: Computer Information Automation UDF Library for AutoIt3 - EXAMPLES Filename: CompInfoExamples.au3 Description: Examples using the UDF's from CompInfo.au3 Author: Jarvis J. Stubblefield (JSThePatriot) http://www.vortexrevolutions.com/ Version: 00.03.08 Last Update: 11.09.06 Requirements: AutoIt v3.2 +, Developed/Tested on WindowsXP Pro Service Pack 2 Notes: Errors associated with incorrect objects will be common user errors. AutoIt beta 3.1.1.63 has added an ObjName() function that will be used to trap and report most of these errors. Special thanks to Firestorm (Testing, Use), Koala (Testing, Bug Fix), and everyone else that has helped in the creation of this Example File. #comments-end #endregion Header #region Global Variables and Constants If Not(IsDeclared("$cI_CompName")) Then Global $cI_CompName = @ComputerName EndIf Global Const $cI_VersionInfo = "00.03.08" Global Const $cI_aName = 0, _ $cI_aDesc = 4 Global $wbemFlagReturnImmediately = 0x10, _ ;DO NOT CHANGE $wbemFlagForwardOnly = 0x20 ;DO NOT CHANGE Global $ERR_NO_INFO = "Array contains no information", _ $ERR_NOT_OBJ = "$colItems isnt an object" #endregion Global Variables and Constants #Region Boot Configuration Dim $BootConfig _ComputerGetBootConfig($BootConfig) If @error Then $error = @error $extended = @extended Switch $extended Case 1 _ErrorMsg($ERR_NO_INFO) Case 2 _ErrorMsg($ERR_NOT_OBJ) EndSwitch EndIf For $i = 1 To $BootConfig[0][0] Step 1 MsgBox(0, "Test _ComputerGetBootConfig", "Name: " & $BootConfig[$i][0] & @CRLF & _ "Boot Directory: " & $BootConfig[$i][1] & @CRLF & _ "Configuration Path: " & $BootConfig[$i][2] & @CRLF & _ "Last Drive: " & $BootConfig[$i][3] & @CRLF & _ "Description: " & $BootConfig[$i][4] & @CRLF & _ "Scratch Directory: " & $BootConfig[$i][5] & @CRLF & _ "Setting ID: " & $BootConfig[$i][6] & @CRLF & _ "Temp Directory: " & $BootConfig[$i][7]) Next #endregion Boot Configuration #region ---- Internal Functions Func _ErrorMsg($message, $time = 0) MsgBox(48 + 262144, "Error!", $message, $time) ConsoleWrite("Error!" & $message & $time & @CRLF) EndFunc #endregion Internal Functions Func _ComputerGetBootConfig(ByRef $aBootConfigInfo) Local $colItems, $objWMIService, $objItem Dim $aBootConfigInfo[1][8], $i = 1 $objWMIService = ObjGet("winmgmts:\\" & $cI_Compname & "\root\CIMV2") $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_BootConfiguration", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) Then For $objItem In $colItems ReDim $aBootConfigInfo[UBound($aBootConfigInfo) + 1][8] $aBootConfigInfo[$i][0] = $objItem.Name $aBootConfigInfo[$i][1] = $objItem.BootDirectory $aBootConfigInfo[$i][2] = $objItem.ConfigurationPath $aBootConfigInfo[$i][3] = $objItem.LastDrive $aBootConfigInfo[$i][4] = $objItem.Description $aBootConfigInfo[$i][5] = $objItem.ScratchDirectory $aBootConfigInfo[$i][6] = $objItem.SettingID $aBootConfigInfo[$i][7] = $objItem.TempDirectory $i += 1 Next $aBootConfigInfo[0][0] = UBound($aBootConfigInfo) - 1 If $aBootConfigInfo[0][0] < 1 Then SetError(1, 1, 0) EndIf Else SetError(1, 2, 0) EndIf EndFunc ;_ComputerGetBootConfig  
×