asweigart / PyGetWindow

A simple, cross-platform module for obtaining GUI information on applications' windows.
BSD 3-Clause "New" or "Revised" License
359 stars 69 forks source link

Window.activate() not working in Jupyter Notebook #16

Open DleanJeans opened 5 years ago

DleanJeans commented 5 years ago

Works fine in a cmd but when I run it on a Jupyter Notebook (Colab local runtime):

import pyautogui
pyautogui.getWindowsWithTitle('Code')[0].activate()

VSCode flashes on the taskbar but never activated. image

Strangely if I focus the window first with pywinauto:

import pywinauto
pywinauto.application.Application().connect(best_match='Code').top_window().set_focus()

then it would work normally, until I restarted the notebook. This only affects one window, other windows have to be focused with pywinauto before being able to be activated with pygetwindow.

Kernel output:

---------------------------------------------------------------------------
PyGetWindowException                      Traceback (most recent call last)
<ipython-input-2-f7654fe7bc43> in <module>()
      1 
      2 import pyautogui
----> 3 pyautogui.getWindowsWithTitle('Code')[0].activate()

c:\users\dleanjeans\appdata\local\programs\python\python36\lib\site-packages\pygetwindow\_pygetwindow_win.py in activate(self)
    282         result = ctypes.windll.user32.SetForegroundWindow(self._hWnd)
    283         if result == 0:
--> 284             _raiseWithLastError()
    285 
    286 

c:\users\dleanjeans\appdata\local\programs\python\python36\lib\site-packages\pygetwindow\_pygetwindow_win.py in _raiseWithLastError()
     95     information from GetLastError() and FormatMessage()."""
     96     errorCode = ctypes.windll.kernel32.GetLastError()
---> 97     raise pygetwindow.PyGetWindowException('Error code from Windows: %s - %s' % (errorCode, _formatMessage(errorCode)))
     98 
     99 

PyGetWindowException: Error code from Windows: 0 - The operation completed successfully.
jxramos commented 4 years ago

I'm seeing the same thing in Windows simply trying to connect to a Notepad window. I'm using click on the window to achieve an activation instead

fw = pyautogui.getWindowsWithTitle('Notepad')
fw = fw[0]
fw.maximize()
pyautogui.click(fw.center); pyautogui.write('abc', 0.01)
AllHarmDone commented 4 years ago

Hello guys,

I have encountered the same issue and I'm sorry if my anwser/workaround looks novice but thats what I am so yeah.

Searching for the reason why this happens I fell down the rabbit whole but I think I some what have an anwser but unfortunately I did not find the sollution. Any how what appears to be happening that it does not find a procces/window to foccus on when the funtion is called. Just the program. Once you use the following as an example:

import pywinauto
import pygetwindow as gw
def focus_to_window(window_title=None):
    window = gw.getWindowsWithTitle(window_title)[0]
    if window.isActive == False:
        pywinauto.application.Application().connect(handle=window._hWnd).top_window().set_focus()

It now seems to bee connected to the procces. after a function like this it seems that the .activate() function seems to work perfectly fine since its pointed to that procces. Until it is minimized because there in no window to focus on.

I have tested it with multiple windows of notepad and looks like it keeps connected to one specific window since "its pointed" to there to bring it to the foreground.

Hopefully I can find the precise reason and get a fully working sollution instead of a workaround

cheers

weki47 commented 4 years ago

I use the following workaround:

<import` pygetwindow, mouse

def activate(win): win.restore() mouse.move(*win.center) mouse.click(button='left')>

type(win) <class 'pygetwindow._pygetwindow_win.Win32Window'> ``

hicpg commented 3 years ago

Please try run Application with administrator privileges in Windows10. This may solve activate error.

khalius commented 3 years ago

I'm not pretty sure why this happens, but I also have a workaround that may look cleaner:

import pygetwindow as gw
hwnd = gw.getWindowsWithTitle('Notepad')
if hwnd != []:
    try:
        hwnd[0].activate()
    except:
        hwnd[0].minimize()
        hwnd[0].maximize()

What we do here is try to activate the desired window, then, if this fails, minimize and maximize the same window. No need to import extra libraries or complicated procedures.

jl1011 commented 2 years ago

I'm not pretty sure why this happens, but I also have a workaround that may look cleaner:

import pygetwindow as gw
hwnd = gw.getWindowsWithTitle('Notepad')
if hwnd != []:
    try:
        hwnd[0].activate()
    except:
        hwnd[0].minimize()
        hwnd[0].maximize()

What we do here is try to activate the desired window, then, if this fails, minimize and maximize the same window. No need to import extra libraries or complicated procedures.

This works great! the only thing I'd add is that I also used hwnd[0].restore() at the end, because my program isn't maximized. So now it works great!

DanielJean007 commented 1 year ago

What worked for me was:

import pyautogui as pag

WINDOW_NAME = "WINDOW NAME OF YOUR APP"

app_window = pag.getWindowsWithTitle(WINDOW_NAME)
if len(app_window) > 0:
        print("Application is running...")
    else:
        print("Application is not running...")
        return False

if app_window[0].isActive == False:
        pag.click(app_window[0].activate())
        print("Brought window application to the foreground.")
    else:
        print("Application already in foreground.")

    return True

The trick was the pag.click(app_window[0].activate()) part.

HammadRafique29 commented 1 year ago

hwnd = gw.getWindowsWithTitle('Notepad') if hwnd != []: try: hwnd[0].activate() except: hwnd[0].minimize() hwnd[0].maximize()

This actually works, Thanks Man

mkq10 commented 1 year ago

I'm not pretty sure why this happens, but I also have a workaround that may look cleaner:

import pygetwindow as gw
hwnd = gw.getWindowsWithTitle('Notepad')
if hwnd != []:
    try:
        hwnd[0].activate()
    except:
        hwnd[0].minimize()
        hwnd[0].maximize()

What we do here is try to activate the desired window, then, if this fails, minimize and maximize the same window. No need to import extra libraries or complicated procedures.

It worked. thanks

chrismajewski commented 10 months ago

The trick was the pag.click(app_window[0].activate()) part.

This didn't work for me as written but it got me over the hump and yours lead to what I think is the most elegant solution. You don't need to minimize, maximize, check if activated. You just need to click() and activate().

import pygetwindow as gw import pyautogui as ag

for window in gw.getWindowsWithTitle(''): ... loop and regex to the window you want ... ag.click() window.activate()

Many thanks

5yes commented 8 months ago

https://github.com/asweigart/PyGetWindow/issues/36#issuecomment-919332733

window.minimize() window.restore()

window.minimize() is used to minimize the specified window, hiding it in the taskbar or system tray. window.restore() is used to restore a minimized window to its normal state, bringing it back from the taskbar or system tray and displaying it again on the screen.

MarcuzziFranco commented 5 months ago

LLego años tarde y en español pero esto funciono para mi Agreguen el envio de ese cartacter antes de cambiar el foco. Todos los creditos a los sabios de aqui https://stackoverflow.com/questions/14295337/win32gui-setactivewindow-error-the-specified-procedure-could-not-be-found

import win32gui, win32com.client shell = win32com.client.Dispatch("WScript.Shell") shell.SendKeys('%') win32gui.SetForegroundWindow(window)