How to get count of icons in tray using pywinauto - python

I have an app which sits in tray when I click on .exe file.
I am unable click on my app which sit in system tray. Because it doesn't have class_name or id or anything when I inspect using inspector.exe. So I decided to click this using index of icon. As I am not sure how many icons sit in tray when I run this particular program. So I wanted to get the count of the icon before I click the .exe file. If the count is x then I can click index x icon after clicking the .exe which actually clicks on my desired icon.
Can any one help me in getting the count of the icons. I tried multiple times using child_window(class_name="") but it returned just an object instead of list.
Below is my code:
from pywinauto.application import Application
import time
app = Application(backend="uia").connect(path="explorer.exe")
st = app.window(class_name="Shell_TrayWnd")
t = st.child_window(title="Notification Chevron").wrapper_object()
t.click()
time.sleep(1)
list_box = Application(backend="uia").connect(class_name="NotifyIconOverflowWindow")
list_box_win = list_box.window(class_name="NotifyIconOverflowWindow")
list_box_win.wait('visible', timeout=30, retry_interval=3)
list_box_win.child_window(class_name="", found_index=x).click_input()
Your help will be much appreciated :)

This is not giving the count and do the required job.
The following code will loop through the apps available in the system tray and clicks on the desired app by checking its name.
from pywinauto.application import Application
import time
app = Application(backend="uia").connect(path="explorer.exe")
taskBar = app.window(class_name='Shell_TrayWnd')
trayIcon = taskBar["Notification Chevron"].wrapper_object()
trayIcon.click()
time.sleep(0.25)
trayWindowContainer = Application(backend="uia").connect(class_name="NotifyIconOverflowWindow")
trayWindow = trayWindowContainer.window(class_name="NotifyIconOverflowWindow")
trayWindow.wait('visible', timeout=30, retry_interval=3)
breakLoop: bool = False
for notification_area in trayWindow.children():
for app_in_tray in notification_area.children():
if "<App_name>" in str(app_in_tray):
app_in_tray.click_input()
breakLoop = True
break
if breakLoop:
break

Related

Can't set focus on Device Manager window after connecting using Pywinauto

I've tried several ways to get the focus placed on the device manager window in Windows 10. I have a lot of notes in the code snippet so I can keep track of what I've tried. I'm able to open device manager but can't seem to focus on it. I've tried things I've seen on stackoverflow, Youtube, and Google.
from pywinauto import Application, keyboard, mouse, findwindows
import time
# app = Application(backend="uia").start(r'mmc devmgmt.msc') # mmc.exe spawns a child process
# app = Application(backend="uia").connect(path='mmc.exe') # connect to a child one
#
# '''
# The way Device Manager is opened causes a popup to display. The popup states:
# You are logged on as a standard user. You can view device settings in Device
# Manager, but you must be logged on as an administrator to make changes.
# ** Opening it this way, I can't Uninstall devices. It has to be opened a different way. **
# '''
# dlgBox = app.DeviceManager.child_window(title="OK", auto_id="2", control_type="Button").wrapper_object()
# dlgBox.click_input() # Click on the OK button
#
# menuView = app.DeviceManager.child_window(title="View", control_type="MenuItem").wrapper_object()
# menuView.click_input() # Clicks the View menu item
# keyboard.send_keys('w') # Press w to select Show hidden devices
# Opening this way I can Uninstall devices
keyboard.send_keys("{LWIN down}" "r" "{LWIN up}") # Press the Winows key and R to open the Run dialog
keyboard.send_keys("devmgmt.msc" "{ENTER}") # Type devmgmt.msc into the Run dialog then press enter
'''
Right click Accessibility Insights for Windows and select Run Elevated with Defendpoint.
With Device Manager open, hover the mouse over the title bar.
Pause Live Inspect.
Select window 'Device Manager' to see all of its elements.
ProcessID = 23356, open Task Manager and look at Details, sort by PID. 23356 belongs to MMC.exe
'''
className = 'MMCMainFrame'
name = 'Device Manager'
# The pritn statements are for troubleshooting along the way, remove once working.
time.sleep(1) # wait 1 second to make sure window is open, without it was happening too fast and would sometimes error.
mywin = findwindows.find_window(active_only=True, class_name=className, title_re=name)
print("Device Manager handle = " + str(mywin)) # this is the handle for the window
app = Application(backend="uia").connect(handle=mywin)
print("app = " + str(app))
# Select View from the menu options then press the w key to select Show hidden devices
# menuView = app.DeviceManager.child_window(title="View", control_type="MenuItem")
# menuView.click_input() # Clicks the View menu item
# keyboard.send_keys('w') # Type w to select Show hidden devices
win = app.window(title_re=name)
print("win = " + str(win))
dlg = app[name]
print("dlg = " + str(dlg))
'''
I can open Device Manager but nothing I have tried is giving the window focus so I can't do anything else.
'''
# *** This is where I simply try to maximize the windows to see if I have the focus set. ***
# Maximize the Device Manager window
# maxWindow = app.DeviceManager.child_window(title="Maximize", control_type="Button")
# maxWindow.click_input() # Click the maximize button
I've tried opening Device Manager this way:
app = Application(backend="uia").start(r'mmc devmgmt.msc') # mmc.exe spawns a child process
app = Application(backend="uia").connect(path='mmc.exe') # connect to a child one
That does indeed open it but it opens in a way that I can't uninstall any devices.
I discovered that I can open it this way (this is currently how I'm opening it).
keyboard.send_keys("{LWIN down}" "r" "{LWIN up}") # Press the Windows key and R to open the Run dialog
keyboard.send_keys("devmgmt.msc" "{ENTER}") # Type devmgmt.msc into the Run dialog then press enter
Then I get the handle of the device manager window.
mywin = findwindows.find_window(active_only=True, class_name=className, title_re=name)
The connect to it, or at least I thought so.
app = Application(backend="uia").connect(handle=mywin)

How to get Menu Item Enabled Status in Pywinauto?

I want to select the menu item Log In in File and check if it is enabled or no. I tried using menu_select but not able to get. Also used py_inspect.py to get a tree there we can find the app status if it enabled how to get. Please find below an image of py_inspect.py application control id tree.
py_inspect.py app tree Image, I want to popup image to the user if the application is logged out. If login is disabled I want to select menu item order->placeOrder and open order window.
from pywinauto import Application
import time
import pywinauto
from pywinauto import Desktop
windows = Desktop(backend="uia").windows()
print([w.window_text() for w in windows])
window_title = "Trader"
app = Application().connect(title=window_title)
top_window = app.top_window()
top_window_name = top_window.window_text()
print("Top Window of App - " + top_window_name)
if top_window_name == "Log In":
print("Top Window is Log In")
elif top_window_name == window_title:
print("Main Window is On Top")
else :
print("Not Top Window Found")
top_window.dump_tree(depth=2)
Tried with adding ...
login_status = top_window.Menubar.File.Log_In.element_info.enabled()
But not sucessfull.

Handling Context Menu of the taskbar icon with pywinauto

I am trying to automate the exiting operation on one of the apps. The app's icon is located in the taskbar. I was successfull in opening that icon's context menu with the modified code that I have found on stackoverflow:
import pywinauto
from pywinauto.application import Application
import time
app= "Service is enabled."
app = Application(backend="uia").connect(path="explorer.exe")
st = app.window(class_name="Shell_TrayWnd")
t = st.child_window(title="Notification Chevron").wrapper_object()
t.click()
time.sleep(1)
list_box = Application(backend="uia").connect(class_name="NotifyIconOverflowWindow")
list_box_win = list_box.window(class_name="NotifyIconOverflowWindow")
list_box_win.wait('visible', timeout=30, retry_interval=3)
# time.sleep(1)
appOpened= list_box_win.child_window(title = app)
appOpened.click_input(button = "right")
After the execution of the code above I get to the point when the context menu is opened:
The next thing that I want to do is to click on Exit, I have tried doing it by specifying the mouse click coordinates, but I have noticed that the position of the parent icon is changing from time to time.
What I would like to do is to get the handle on the Exit button and send click automatically.
------Edit-------
The icon is located in the hidden icons
So you want to access to the right click context menu. As said in this answer, you can do something like :
listbox.PopupMenu["Exit"].set_focus().click_input()

Right click on taskbar icon then select on popupmenu

This is my code to right click on the app selected :
import pywinauto
#import time
from pywinauto.application import Application
app = Application(backend="uia").connect(path="explorer.exe")
taskbar = app.window(class_name="Shell_TrayWnd")
taskbar.child_window(title="myApp").click_input(button='right')
app.PopupMenu.MenuClick("Open")
But then I can't choose "Open" on the popupmenu, which is Open or Exit.
Everything work until the MenuClick().
How can I do that ?

Python - How to interact with system tray popup

I want to autologin to an app via its system tray icon.
I use the pywinauto module to interact with the tray icon to launch the app and now I have a popup who ask me to log on.
But... I don't know how to interact with it !
This is my icon :
Tray Icon
Here, an extract of my code (works fine) :
_pApp = Application().connect(path='my_app_dir')
taskbar.ClickSystemTrayIcon(1)
_pApp.PopupMenu.menu_item('submenu').click_input()
_pApp.PopupMenu.menu_item('another_submenu').click_input()
How can I interact with the popup authentication window below ?
Popup window
Thanks for your help.
I finally found a solution with pywinauto.keyboard. I don't know if it's clean but it works.
from pywinauto.keyboard import *
[...]
send_keys(_user)
send_keys("{VK_TAB}")
send_keys(_pass)
send_keys("{ENTER}")
Finally, I found exactly the expected behavior :)
Thank you Vasily Ryabov ! Your method is very helpful !
I do not use 'send_keys' anymore.
from tkinter.messagebox import *
from pywinauto import taskbar
from pywinauto.application import Application
[...]
_user = "TOTO"
_pass = "TOTOPASS"
app_dir = r'C:\Program Files\Common Files\App\App.exe'
icon_list = list()
# Getting the name of the icons in the sys tray
for i in range(0, 13):
app_sti = taskbar.SystemTrayIcons.wrapper_object()
app_stv = pulse_sti.button(i).info.text
icon_list.append(app_stv)
# Looking for my app name
try:
if "App_name" in str(icon_list):
app = Application().connect(path=app_dir)
taskbar.ClickSystemTrayIcon("App name")
app.PopupMenu.menu_item('menu').click_input()
app.PopupMenu.menu_item('menu -> submenu').click_input()
app_auth = Application(backend="uia").connect(title_re="Title*", timeout=5)
app_auth_window = app_auth.window(title_re="Title*")
app_auth_window.child_window(title="User :", control_type="Edit").set_text(_user)
app_auth_window.child_window(title="Password :", control_type="Edit").set_text(_pass)
app_auth_window.child_window(title="Connect", control_type="Button").click()
except Exception as error:
showwarning("Error", "App not found !")
Currently, I re-write a part of my code :
from pywinauto import taskbar
from pywinauto.application import Application
from pywinauto.keyboard import *
from tkinter.messagebox import *
[...]
app_dir = r'C:\Program Files\Common Files\App\App.exe'
_user = "TOTO"
_pass = "TOTOPASS"
# Check if my app has its system tray icon in the taskbar
for i in range(0, 10):
tsIcon = taskbar.SystemTrayIcons.wrapper_object()
tsValue = tsIcon.button(i).info.text
# If I find it, the code click on it and its menu until the popup auth window come
if "App_name" in tsValue:
_pApp = Application().connect(path=app_dir)
taskbar.ClickSystemTrayIcon(i)
_pApp.PopupMenu.menu_item('menu').click_input()
_pApp.PopupMenu.menu_item('menu->submenu').click_input()
time.sleep(2)
# When the popup window comes out, I run 'send_keys'
send_keys(_user)
send_keys("{VK_TAB}")
send_keys(_pass)
send_keys("{ENTER}")
else:
showwarning("Error", "App not found !")
[...]
My code seems good ? There is another "most clean" method ?
Thanks

Categories

Resources