Jump to content

Issues with getting window handles


Recommended Posts

So this is strange. I am not new to using Autoit, and I have made numerous scripts that work just fine using the WinActive, WinExists, WinWaitActive type functions, but it is **not** working for me and I am befuddled.

Basically, I have a script that launches a series of executables, web browser windows, etc. from an INI file. So I "Run" the program, I capture the PID and I capture the window handle.

I use these to basically complement a remote control function of my HTPC. Sometimes Kodi, or WMC, or even  web browser may act up, so the easiest thing to do is kill that process, but overall I like to (and prefer to), toggle the windows via window handles. So I have a function that launches the EXE, and captures the handle to an array. Well, strangely enough, if I just do a WinActive("[ACTIVE]") call, it gives me the correct window handles.

However, when I call it with Title text (I have used 2 and -2 for AutoItSetOption("WinTitleMatchMode", -2)), and have used variations of this script for **YEARS** without issue. Now that I am trying to reference it with Arrays, it is all kinds of broken.

Here is a current as ran set of code, full of debug garbage because I've been tweaking and intentionally trying to force it to report DIFFERENT window handles... but what I am getting is bizzare:

;this loads the specified window if not already loaded, loads all if bad value
Func CheckAndLoadMedia($winNum = -1)
    ;ToolTip("Win# is: " & $winNum, 20, 10, 0)
    ;Sleep(5000)
    If $winNum = -1 Then
        If @HotKeyPressed Then
            ;ToolTip("HotkeyPressed to load is: " & @HotKeyPressed, 20, 10, 0)
            Sleep(5000)
            $winNum = GetHotkeyWindowNumber(@HotKeyPressed)   ;sets -1 if errored
        EndIf
    EndIf
    If $winNum = -1 Then   ;if we still have a -1, give up, force load everything
        ;CheckAndLoadAllMedia()
        Return 0
    EndIf
    ;Check to see if either the window, or the window handle (at least) doesn't exist already
    If WinExists($WindowTexts[$winNum]) = 0 Or WinExists($WindowHandles[$winNum]) = 0 Then
        ;if we get here, then we think it isn't running, so I want to tell it to kill the last process (just in case)
        ;ToolTip("DNE Window Texts: " & $WindowTexts[$winNum] & " or Handle: " & $WindowHandles[$winNum], 20, 10, 0)
        ;Sleep(5000)
        FileWriteLine("D:\test_file.txt",  "1:" & WinActivate($WindowTexts[$winNum]) & ":" & $WindowHandles[$winNum])
        If ProcessExists($WindowPIDs[$winNum]) And $WindowPIDs[$winNum] <> 0 Then
            ;ToolTip("Killing PID for: " & $WindowNames[$winNum], 20, 10, 0)
            ;Sleep(5000)
            ProcessClose($WindowPIDs[$winNum])
            $WindowPIDs[$winNum] = 0
            Sleep(500)
        EndIf
        ;now we feel it is dead, and we can re-launch accordingly
        ToolTip("Running Window[" & $winNum & "]: " & $WindowNames[$winNum] & " and look for text: " & $WindowTexts[$winNum] & " via: " & $WindowExePaths[$winNum], 20, 10, 0)
        Sleep(5000)
        $WindowPIDs[$winNum] = Run($WindowExePaths[$winNum])  ;runs it & stores the new PID
        FileWriteLine("D:\test_file.txt", "2:" & WinActivate($WindowTexts[$winNum]) & $WindowTexts[$winNum] & ":" & $WindowHandles[$winNum])
        Sleep(5000)
        FileWriteLine("D:\test_file.txt",  "3:" & WinActivate($WindowTexts[$winNum])&$WindowTexts[$winNum] & ":" & $WindowHandles[$winNum])
        Do ;lets wait until we know the window exists. This will endless loop if there is an issue
            ToolTip("Waiting on running Window[" & $winNum & "]: " & $WindowNames[$winNum] & " and look for text: " & $WindowTexts[$winNum] & " via: " & $WindowExePaths[$winNum], 20, 10, 0)
            WinWaitActive($WindowTexts[$winNum], "", $windowWait)  ;stalls until it is active & stores the Handle
            $WindowHandles[$winNum] = WinActivate($WindowTexts[$winNum])
            FileWriteLine("D:\test_file.txt",  "4:" & WinActivate($WindowTexts[$winNum])&$WindowTexts[$winNum] & ":" & $WindowHandles[$winNum])
        Until (WinExists($WindowTexts[$winNum]) And  $WindowHandles[$winNum] <> 0)
        ;$WindowHandles[$winNum] = WinWaitActive($WindowTexts[$winNum])  ;stalls until it is active & stores the Handle
        ;$WindowHandles[$winNum] = WinGetHandle("[ACTIVE]")  ;stalls until it is active & stores the Handle)
        FileWriteLine("D:\test_file.txt",  "6:" & WinActivate($WindowTexts[$winNum])&$WindowTexts[$winNum] & ":" & $WindowHandles[$winNum])
        ToolTip("Got Window Handle[" & $winNum & "]:" & $WindowHandles[$winNum], 20, 10, 0)
        Sleep(5000)
        $lastWindow = $winNum
    EndIf
EndFunc   ;==>CheckAndLoadMedia

My result from that run which blows my mind is this:

1:0:0
2:0x00000000043D086E"Kodi":0
3:0x00000000043D086E"Kodi":0
4:0x00000000043D086E"Kodi":0x00000000043D086E
6:0x00000000043D086E"Kodi":0x00000000043D086E
1:0:0
2:0x00000000043D086E"Netflix":0
3:0x00000000043D086E"Netflix":0
4:0x00000000043D086E"Netflix":0x00000000043D086E
6:0x00000000043D086E"Netflix":0x00000000043D086E
1:0:0
2:0x00000000043D086E"Amazon.com: Prime":0
3:0x00000000043D086E"Amazon.com: Prime":0
4:0x00000000043D086E"Amazon.com: Prime":0x00000000043D086E
6:0x00000000043D086E"Amazon.com: Prime":0x00000000043D086E
1:0:0
2:0x00000000043D086E"Verizon FIOS":0
3:0x00000000043D086E"Verizon FIOS":0
4:0x00000000043D086E"Verizon FIOS":0x00000000043D086E
6:0x00000000043D086E"Verizon FIOS":0x00000000043D086E

So the function is entered with a value passed to an array, which in turn maps to the various programs being launched. As you can see, the text I am looking for such as Kodi is changing with each call. Also, the array value for the text is changed and the file being written proves it.... So clearly, the WinActivate() function is literally returning the same window handle on all of the windows.... this is totally NOT true. Furthermore, the window handle it is returning is bogus.

The endless loop should happen if its not finding the window I want, but line #6: is getting written which means Autoit thinks it found my desired window handle, and assigns it to the array, as seen by the 0's followed by the bogus handle...

 

Link to comment
Share on other sites

So, I intentionally added hand entered text (vs the array values) as will be seen in the code below, and the result was correct for the NON-ARRAY entries. As mentioned before, this is ugly, because I'm debugging, but I believe this proves reading from the arrays in the Window functions is broken. I generally avoid arrays in AutoIT, but my goal here was to allow any number of ini entries for windows to be launched, and make the program flexible enough to do so without having handlers for eah exe/window.

I'm going to look into eval() but I don't understand why or if this should be needed. The way it is behaving seems to be a bug.

;this loads the specified window if not already loaded, loads all if bad value
Func CheckAndLoadMedia($winNum = -1)
    ;ToolTip("Win# is: " & $winNum, 20, 10, 0)
    ;Sleep(5000)
    If $winNum = -1 Then
        If @HotKeyPressed Then
            ;ToolTip("HotkeyPressed to load is: " & @HotKeyPressed, 20, 10, 0)
            Sleep(5000)
            $winNum = GetHotkeyWindowNumber(@HotKeyPressed)   ;sets -1 if errored
        EndIf
    EndIf
    If $winNum = -1 Then   ;if we still have a -1, give up, force load everything
        ;CheckAndLoadAllMedia()
        Return 0
    EndIf
    ;Check to see if either the window, or the window handle (at least) doesn't exist already
    If WinExists($WindowTexts[$winNum]) = 0 Or WinExists($WindowHandles[$winNum]) = 0 Then
        ;if we get here, then we think it isn't running, so I want to tell it to kill the last process (just in case)
        ;ToolTip("DNE Window Texts: " & $WindowTexts[$winNum] & " or Handle: " & $WindowHandles[$winNum], 20, 10, 0)
        ;Sleep(5000)
        FileWriteLine("D:\test_file.txt",  "1:" & WinActivate($WindowTexts[$winNum]) & ":" & $WindowHandles[$winNum])
        If ProcessExists($WindowPIDs[$winNum]) And $WindowPIDs[$winNum] <> 0 Then
            ;ToolTip("Killing PID for: " & $WindowNames[$winNum], 20, 10, 0)
            ;Sleep(5000)
            ProcessClose($WindowPIDs[$winNum])
            $WindowPIDs[$winNum] = 0
            Sleep(500)
        EndIf
        ;now we feel it is dead, and we can re-launch accordingly
        ToolTip("Running Window[" & $winNum & "]: " & $WindowNames[$winNum] & " and look for text: " & $WindowTexts[$winNum] & " via: " & $WindowExePaths[$winNum], 20, 10, 0)
        Sleep(5000)
        $WindowPIDs[$winNum] = Run($WindowExePaths[$winNum])  ;runs it & stores the new PID
        FileWriteLine("D:\test_file.txt", "2:" & WinActivate($WindowTexts[$winNum]) & $WindowTexts[$winNum] & ":" & $WindowHandles[$winNum])
        Sleep(5000)
        FileWriteLine("D:\test_file.txt",  "3:" & WinActivate($WindowTexts[$winNum])&$WindowTexts[$winNum] & ":" & $WindowHandles[$winNum])
        Do ;lets wait until we know the window exists. This will endless loop if there is an issue
            ToolTip("Waiting on running Window[" & $winNum & "]: " & $WindowNames[$winNum] & " and look for text: " & $WindowTexts[$winNum] & " via: " & $WindowExePaths[$winNum], 20, 10, 0)
            WinWaitActive($WindowTexts[$winNum], "", $windowWait)  ;stalls until it is active & stores the Handle
            $WindowHandles[$winNum] = WinActivate($WindowTexts[$winNum])
            FileWriteLine("D:\test_file.txt",  "4:" & WinActivate($WindowTexts[$winNum])&$WindowTexts[$winNum] & ":" & $WindowHandles[$winNum])
            $WindowHandles[$winNum] = WinActivate("Kodi")
            FileWriteLine("D:\test_file.txt",  "4.1:" & WinActivate("Kodi")&$WindowTexts[$winNum] & ":" & $WindowHandles[$winNum])
            $WindowHandles[$winNum] = WinActivate("Netflix")
            FileWriteLine("D:\test_file.txt",  "4.2:" & WinActivate("Netflix")&$WindowTexts[$winNum] & ":" & $WindowHandles[$winNum])
            $WindowHandles[$winNum] = WinActivate("Amazon.com: Prime")
            FileWriteLine("D:\test_file.txt",  "4.3:" & WinActivate("Amazon.com: Prime")&$WindowTexts[$winNum] & ":" & $WindowHandles[$winNum])
            $WindowHandles[$winNum] = WinActivate("Verizon FIOS")
            FileWriteLine("D:\test_file.txt",  "4.4:" & WinActivate("Verizon FIOS")&$WindowTexts[$winNum] & ":" & $WindowHandles[$winNum])
        Until (WinExists($WindowTexts[$winNum]))
        $WindowHandles[$winNum] = WinActivate($WindowTexts[$winNum])
        ;Until (WinExists($WindowTexts[$winNum]) And  $WindowHandles[$winNum] <> 0)
        ;$WindowHandles[$winNum] = WinWaitActive($WindowTexts[$winNum])  ;stalls until it is active & stores the Handle
        ;$WindowHandles[$winNum] = WinGetHandle("[ACTIVE]")  ;stalls until it is active & stores the Handle)
        FileWriteLine("D:\test_file.txt",  "6:" & WinActivate($WindowTexts[$winNum])&$WindowTexts[$winNum] & ":" & $WindowHandles[$winNum])
        ToolTip("Got Window Handle[" & $winNum & "]:" & $WindowHandles[$winNum], 20, 10, 0)
        Sleep(5000)
        $lastWindow = $winNum
    EndIf
EndFunc   ;==>CheckAndLoadMedia

 

The file output was:

1:0:0
2:0x00000000006E0DBE"Kodi":0
3:0x00000000006E0DBE"Kodi":0
4:0x00000000006E0DBE"Kodi":0x00000000006E0DBE
4.1:0x00000000006E0DBE"Kodi":0x00000000006E0DBE
4.2:0"Kodi":0
4.3:0"Kodi":0
4.4:0"Kodi":0
6:0x00000000006E0DBE"Kodi":0x00000000006E0DBE
1:0:0
2:0x00000000006E0DBE"Netflix":0
3:0x00000000006E0DBE"Netflix":0
4:0x00000000006E0DBE"Netflix":0x00000000006E0DBE
4.1:0x0000000000590D68"Netflix":0x0000000000590D68
4.2:0x00000000006E0DBE"Netflix":0x00000000006E0DBE
4.3:0"Netflix":0
4.4:0"Netflix":0
6:0x00000000006E0DBE"Netflix":0x00000000006E0DBE
1:0:0
2:0x00000000006E0DBE"Amazon.com: Prime":0
3:0x00000000006E0DBE"Amazon.com: Prime":0
4:0x00000000006E0DBE"Amazon.com: Prime":0x00000000006E0DBE
4.1:0x0000000000590D68"Amazon.com: Prime":0x0000000000590D68
4.2:0x0000000002BE091E"Amazon.com: Prime":0x0000000002BE091E
4.3:0x00000000006E0DBE"Amazon.com: Prime":0x00000000006E0DBE
4.4:0"Amazon.com: Prime":0
6:0x00000000006E0DBE"Amazon.com: Prime":0x00000000006E0DBE
1:0:0
2:0x00000000006E0DBE"Verizon FIOS":0
3:0x00000000006E0DBE"Verizon FIOS":0
4:0x00000000006E0DBE"Verizon FIOS":0x00000000006E0DBE
4.1:0x0000000000590D68"Verizon FIOS":0x0000000000590D68
4.2:0x0000000002BE091E"Verizon FIOS":0x0000000002BE091E
4.3:0x00000000034206FC"Verizon FIOS":0x00000000034206FC
4.4:0x00000000006E0DBE"Verizon FIOS":0x00000000006E0DBE
6:0x00000000006E0DBE"Verizon FIOS":0x00000000006E0DBE

 

As seen above, when the plan text of the window was referenced that was required, the output from WinActive was also correct

Link to comment
Share on other sites

FYI...I've also now tried this "explicitly":

$val = $WindowTexts[$winNum]
$WindowHandles[$winNum] = WinActivate("[TITLE:"& $val &"]")
FileWriteLine("D:\test_file.txt",  "4.5:" & $val & ":" & $WindowHandles[$winNum])

And still not working. I have never used variables in place of TITLE text, but I never expected this kind of behavior using it directly. Please advise if there is something I'm overlooking here.

Link to comment
Share on other sites

It was a real P.I.T.A to figure out what it is doing, and I'm still not certain why it caused an issue, but since the text string already included a '"' (double quote), this was being passed into the Window function on top of the variable, which.... I was not adding. This seems to lack some elegance but it makes sense.\

So by either excluding quotes on the INI values or using replace, it works (e.g.,):

Local $var = "[TITLE:" & StringReplace($WindowTexts[$winNum], """", "") & "]"

 

Link to comment
Share on other sites

  • 1 year later...

I was running into the same issue.

Thank you for figuring it out.

*** EDIT *** also setting #AutoIt3Wrapper_UseX64=N will return the 32bit handle as most of the functions don't handle the 64bit, as I am recently discovering.

Edited by Yirrlaar
adding an additional comment
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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...