Search code examples
pythonpycharmpywin32

Issues Adding Variable To getWindowsWithTitle


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?


Solution

  • 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.