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

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)

Related

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()

How to get count of icons in tray using pywinauto

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

GUI Automation of policy change for logoff button. pywinauto.findwindows.ElementNotFoundError: error. How to switch context?

I am automating the steps to change the policy for the logoff button. The steps involved are:
Open Local Group Policy using gpedit.msc
Select "Start Menu and Taskbar" from the dropdown in User Configuration > Administrative Template from the left pane
In the right pane, double click on "Change Start Menu power button"
Select the radio button "Enabled"
From the dropdown menu of options: Select "Log Off"
I have gotten through the third step, but I have a problem in mapping the "Change Start Menu Power Button" from the second step. My code is as below:
from pywinauto import Application
Application().start(r'mmc gpedit.msc')
app = Application(backend="uia").connect(path='mmc.exe')
#app.LocalGroupPolicyEditor.dump_tree()
Admin_template = app.LocalGroupPolicyEditor.child_window(title="User
Configuration", control_type="TreeItem").child_window(title="Administrative
Templates", control_type="TreeItem") # since there are same templates
Admin_template.double_click_input() # it expands the subtree
#Admin_template.dump_tree()
Start_menu = Admin_template.child_window(title="Start Menu and Taskbar",
control_type="TreeItem").double_click_input()
Start_menu.dump_tree()
#Admin_template.child_window(title="Start Menu and Taskbar",
control_type="TreeItem").dump_tree()
#Change_start_menu = Start_menu.child_window(title="Change Start Menu power
#button", control_type="MenuItem").double_click_input()
#Change_start_menu.dump_tree()
I have trouble in finding and mapping the elements in the right pane. Also, when I use Start_menu.dump_tree(), there are only "Notification" elements shown. However, the rest, which includes "Change Start Menu power button," is what I'll be double clicking next.
I appreciate the help. Thanks.
It was kinda tricky, but this should do the job (it does all the steps you've listed - presses OK - and closes the program):
import pywinauto
pywinauto.Application().start(r'mmc gpedit.msc')
app = pywinauto.Application(backend="uia").connect(path='mmc.exe')
admin_template = app.LocalGroupPolicyEditor.child_window(title="User Configuration", control_type="TreeItem").child_window(title="Administrative Templates", control_type="TreeItem")
admin_template.double_click_input()
start_menu = admin_template.child_window(title="Start Menu and Taskbar", control_type="TreeItem")
start_menu.double_click_input()
option_list = app.LocalGroupPolicyEditor.child_window(auto_id="12786", control_type="List")
# Just select any of the first options to change the focus to the list.
first_elem = option_list.child_window(title="Add Search Internet link to Start Menu", control_type="ListItem")
first_elem.click_input()
# Used to scroll down the window so that the wanted option becomes visible.
pywinauto.keyboard.send_keys("cccc")
option = option_list.child_window(title="Change Start Menu power button", control_type="ListItem")
option.double_click_input()
pop_up = app.LocalGroupPolicyEditor.child_window(auto_id="tableLayoutFullForm", control_type="Pane")
radio = pop_up.child_window(title="Enabled", auto_id="radioButtonEnabled", control_type="RadioButton")
radio.click_input()
drop_down = pop_up.child_window(title="Choose one of the following actions", auto_id="dropDownListChoose one of the following actions", control_type="ComboBox")
drop_down.click_input()
# 'Hack' to first select the Restart option and then the next option after that which starts with l (=Log off).
# This ensures that the correct setting gets set despite of what the setting was before.
pywinauto.keyboard.send_keys("rl{ENTER}")
ok = pop_up.child_window(title="OK", auto_id="buttonOK", control_type="Button")
ok.click_input()
app.kill()
Make sure to run this script as administrator or else it will fail.
Feel free to ask if you got any questions about the code :)
Edit:
If you're running a version of pywinauto <0.6.0, you'll have to replace the two occurances (lines 19 and 34) of pywinauto.keyboard.send_keys() with:
pywinauto.SendKeysCtypes.SendKeys()
If that doesn't work you could try:
pywinauto.keyboard.SendKeys()

how to wait until the required window title appers in pywinauto

How to wait until the required window title to be appers using pywinauto?
I have to wait for required window title, once I found that window title have to do some action on that window. How I can do this?
The easiest way is to use pywinauto.timings.WaitUntilPasses
app = pywinauto.Application()
app.start('calc')
window = pywinauto.timings.WaitUntilPasses(10, 0.5, lambda: app.window_(title=u'About Calculator'))
#run About manually in 10 seconds
<pywinauto.application.WindowSpecification object at 0x02DD0DB0>
Ok now i got how to use WaitUntilPasses this method I was trying below small script.
app = pywinauto.Application()
app.start('Notepad')
Win = "Untitled1.txt" + "-" + "Notepad"
window = pywinauto.timings.WaitUntilPasses(20, 0.5, lambda: app.window_(title=Win))
app.Untitled1.MenuSelect('Help -> About Notepad')
Here after opening the notepad within 20sec i saved the notepad with Untitled1.txt and after saving the notpad title of the notepad shown like "Untitled1.txt - Notepad" So in the above script am waiting for the same title and once i got the same title trying to select the menu option in that notepad but after 20sec am getting here am getting timeout error.

Categories

Resources