Jump to content

AutoItX, WinList function memory leak


marc0v
 Share

Recommended Posts

All my tests done on WinXP SP3, AutoItX v3.3.0.0

My AutoItX is not up-to-date, however the changelog does not record any change regarding this problem.

The issue is known :

* each call to o_AutoItX3Obj.WinList can consumme up to 4ko (in my tests),

which are not released even when exiting a sub or setting the o_AutoItX3Obj object to Nothing

-> this is a problem, for example, for ever-runnning scripts that do repetitive call to WinList

* a work-around : enumerate windows instead of using WinList

VBS Code

Option Explicit

MAIN()

Sub MAIN()
    Dim s_win_id, arr
    Dim o_AutoItX3Obj

    Set o_AutoItX3Obj = CreateObject("AutoItX3.Control")

    ' s_win_id : the advanced filter parameter that would have been used in the WinList function
    ' s_win_id : must not contain the INSTANCE parameter (it seems it just would be ignored)
    ' WinTitleMatchMode : the title match mode that would have been used with the WinList function
    ' WinSearchChildren : the child windows mode that would have been used with the WinList function

    ' *** EXAMPLE 1 ***

    ' s_win_id = "TITLE:a", with WinTitleMatchMode substring (=2), No WinSearchChildren (=0)
    ' there should be some of theses
    s_win_id  = "TITLE:a"
    o_AutoItX3Obj.AutoItSetOption "WinTitleMatchMode", 2
    o_AutoItX3Obj.AutoItSetOption "WinSearchChildren", 0

    ' call the pseudo WinList function (ENUM_WIN)
    arr = ENUM_WIN(o_AutoItX3Obj, s_win_id)

    ' look for results
    SHOW_RESULTS o_AutoItX3Obj, s_win_id, arr

    ' *** EXAMPLE 2 ***

    ' s_win_id = "TITLE:a; REGEXPCLASS:a", with WinTitleMatchMode substring (=2), No WinSearchChildren (=0)
    ' there should be at least the 'Program Manager' [Class:Progman], which is the Windows desktop
    s_win_id  = "TITLE:a; REGEXPCLASS:a"
    o_AutoItX3Obj.AutoItSetOption "WinTitleMatchMode", 2
    o_AutoItX3Obj.AutoItSetOption "WinSearchChildren", 0

    ' call the pseudo WinList function (ENUM_WIN)
    arr = ENUM_WIN(o_AutoItX3Obj, s_win_id)

    ' look for results
    SHOW_RESULTS o_AutoItX3Obj, s_win_id, arr
End Sub

Sub SHOW_RESULTS(ByVal o_AutoItX3Obj, ByVal s_win_id, ByVal arr)
    Dim s_res, i

    s_res = "Number of windows matching [" & s_win_id & "] : " & arr(0, 0) & vbCr
    s_res = s_res & "WinTitleMatchMode : " & o_AutoItX3Obj.AutoItSetOption("WinTitleMatchMode", 0) & ", "
    s_res = s_res & "WinSearchChildren : " & o_AutoItX3Obj.AutoItSetOption("WinSearchChildren", 0) & vbCr
    s_res = s_res & "(message boxes can cut long text)" & vbCr & vbCr
    s_res = s_res & "Num Handle" & vbTab & "Title" & vbCr & vbCr

    For i = 1 To UBound(arr, 2)
        s_res = s_res & i & ". " & arr(1, i) & vbTab & "[" & arr(0, i) & "]" & vbCr
    Next

    MsgBox s_res, vbInformation, WScript.ScriptName
End Sub

' Re-usable code begins here (could be optimized if hundreds of matching windows are expected)
' ENUM_WIN returns an 2-Dim array, same formatting as by WinList function
Function ENUM_WIN(ByVal o_AutoItX3Obj, ByVal s_win_id)
    Dim s_win_handle, s_win_title, arr, i

    ReDim arr(1, 0)
    arr(0, 0) = 0 ' will hold the number of found windows, like the WinList function
    arr(1, 0) = 0 ' will not be used

    i = 1 ' because Instances are 1-based
    Do
        s_win_handle = o_AutoItX3Obj.WinGetHandle("[" & s_win_id & "; INSTANCE:" & i & "]")
        If s_win_handle = "" Then Exit Do ' enumeration finished
        s_win_title = o_AutoItX3Obj.WinGetTitle("[HANDLE:" & s_win_handle & "]")

        ReDim Preserve arr(1, i)
        arr(0, i) = s_win_title ' title can be an empty string
        arr(1, i) = s_win_handle ' handle should always be a valid hex string number (32/64 bits ?)

        i = i + 1
    Loop
    arr(0, 0) = i - 1 ' record the number of found windows

    ENUM_WIN = arr
End Function

* note 1 :

enumerating windows could have timing issues if some windows matching the criteria

are appearing/disappearing while doing the enumeration... (I didn't test that)

* note 2 :

if it impossible to avoid memory leak in COM components returning arrays,

then WinList could return a simple string with titles/handles separated by Chr(0),

(assuming there are no Chr(0) inside window titles ?)

then the user would use the Split function to get an 1-Dim array : [title1, handle1, title2, handle2, title3, handle3] etc...

This string-type return could be an optional parameter given to the WinList function :

arr = o_AutoItX3Obj.Winlist("title" [, "text" [, return type]])

Edited by marc0v
Link to comment
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
 Share

×
×
  • Create New...