1

So I am having issues with getWindowsWithTitle function from pygetwindow. When I ask for input before the getWindowsWithTitle call, I get the following error:

Traceback (most recent call last):
  File "*****\main.py", line 79, in <module>
    handle.activate()
  File "*****\venv\lib\site-packages\pygetwindow\_pygetwindow_win.py", line 246, in activate
    _raiseWithLastError()
  File "*****\venv\lib\site-packages\pygetwindow\_pygetwindow_win.py", line 99, in _raiseWithLastError
    raise PyGetWindowException('Error code from Windows: %s - %s' % (errorCode, _formatMessage(errorCode)))
pygetwindow.PyGetWindowException: Error code from Windows: 0 - The operation completed successfully.

If I comment out my Input call, the getWindowsWithTitle works just fine. The following is my code so far

import win32gui
import time
from pynput.keyboard import Key, Controller
import pygetwindow as window


target = input("** Instance Name Is The Title When You Hover Over The Application ** \nSelect Instance Name: ")
handle = window.getWindowsWithTitle('Command')[0]

keyboard = Controller()
handle.activate()
handle.maximize()
time.sleep(2)
keyboard.press('a')
keyboard.release('a')

I am trying to get input to choose which window to select, but even putting "target" in the getWindowsWithTitle it gives me the same error. Does anyone know why I am getting this error after putting in my input?

1 Answers1

1

I've briefly looked a bit over [GitHub]: asweigart/PyGetWindow - PyGetWindow. I strongly suggest against using it as it's buggy (at least the current version):

  1. Major, generic, conceptual flaw. It uses CTypes, but in an incorrect manner. I wonder how come there aren't a lot of bugs submitted against it. Check [SO]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer) for more details

  2. In your particular case, an exception is raised. That behavior is incorrect (you get error code 0, which means success (ERROR_SUCCESS)). [MS.Docs]: SetForegroundWindow function (winuser.h) doesn't specify using GetLastError if the function fails (doesn't do what it should). It's just the window couldn't be brought to front because of some of the mentioned reasons

Since you tagged your question for PyWin32, you could use that.

code00.py:

#!/usr/bin/env python

import sys
import time
import pynput
import win32con as wcon
import win32gui as wgui


# Callback
def enum_windows_proc(wnd, param):
    if wgui.IsWindowVisible(wnd):
        text = wgui.GetWindowText(wnd)
        if param[0] in text.upper():
            print(wnd, text)  # Debug purposes only
            param[1].append(wnd)


def windows_containing_text(text):
    ret = []
    wgui.EnumWindows(enum_windows_proc, (text.upper(), ret))
    return ret


def send_char(wnd, char):
    kb = pynput.keyboard.Controller()
    kb.press(char)
    kb.release(char)


def main(*argv):
    txt = input("Enter text contained by window title: ")
    #txt = "notepad"
    wnds = windows_containing_text(txt)
    print(wnds)
    wnd = wnds[1]  # Notepad in my case (this example only, list might have fewer elements!!!!!)
    try:
        wgui.SetForegroundWindow(wnd)  # Activate
    except:
        print(sys.exc_info())
    wgui.ShowWindow(wnd, wcon.SW_MAXIMIZE)  # Maximize
    time.sleep(1)
    send_char(wnd, "a")


if __name__ == "__main__":
    print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
                                                   64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(*sys.argv[1:])
    print("\nDone.")
    sys.exit(rc)

Check [SO]: Get the title of a window of another program using the process name (@CristiFati's answer) for more details on this WinAPI area.

Output:

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q070373526]> "e:\Work\Dev\VEnvs\py_pc064_03.08.07_test0\Scripts\python.exe" code00.py
Python 3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)] 064bit on win32

Enter text contained by window title: notepad
394988 e:\Work\Dev\StackOverflow\q070373526\code00.py - Notepad++ [Administrator]
4264044 *Untitled - Notepad
[394988, 4264044]

Done.

And an "a" char is inserted in the Notepad window at cursor position.

CristiFati
  • 38,250
  • 9
  • 50
  • 87
  • Thank you for your response, it was very helpful. So as I was running through your code I ran into a couple of things on my end. First if I just have 1 copy of an item open wnd = wnds[1] errors out to the index being out of bounds so I changed it to wnd = wnds[0]. Now I seem to be running into "pywintypes.error: (126, 'SetForegroundWindow', 'The specified module could not be found.')" – LordTakahiro Dec 21 '21 at 00:20
  • Interesting, I found if I do the send_char command before and after the setting of the windows, it works just fine, but if I don't do it before, SetForegroundWindow errors out. – LordTakahiro Dec 21 '21 at 00:26
  • `wnd = wnds[1] # Notepad in my case` as the comment suggests it's in my case and it was particularly for this example, where the list had 2 entries. Regarding the errors you encounter, it's strange. I guess it depends on the window you want to activate, and also on the user type. – CristiFati Dec 21 '21 at 05:38