Last active
September 24, 2020 04:43
-
-
Save statik/0c16fcc216a55ae556640ef5c17fd9d8 to your computer and use it in GitHub Desktop.
uiautomation.py dump of zoom.exe application controls.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Credit for initial script: https://github.com/oldjohngalt | |
# | |
# Martijn Smit <[email protected] / @smitmartijn> | |
import os | |
import sys | |
import time | |
import argparse | |
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
import uiautomation as automation | |
debug = False | |
zoomMeetingOpen = False | |
zoomToolbarOpen = False | |
toggleMute = False | |
toggleVideo = False | |
toggleShare = False | |
def DetectZoomMeeting(): | |
global zoomToolbarOpen | |
global zoomMeetingOpen | |
if debug == True: | |
global start | |
start = time.time() | |
zoomMeetingInProgress = False | |
def GetFirstChild(control): | |
return control.GetFirstChildControl() | |
def GetNextSibling(control): | |
return control.GetNextSiblingControl() | |
desktop = automation.GetRootControl() | |
zoomMeetingOpen = False | |
zoomToolbarOpen = False | |
for control, depth in automation.WalkTree(desktop, getFirstChild=GetFirstChild, getNextSibling=GetNextSibling, includeTop=False, maxDepth=2): | |
if debug == True: | |
print(str(depth) + ' ' * depth * 4 + str(control)) | |
if str(control).find("ZPContentViewWndClass") > 0: | |
zoomMeetingInProgress = True | |
zoomMeetingOpen = True | |
if str(control).find("ZPFloatToolbarClass") > 0: | |
zoomMeetingInProgress = True | |
zoomToolbarOpen = True | |
return zoomMeetingInProgress | |
def GetFirstChild(control): | |
return control.GetFirstChildControl() | |
def GetNextSibling(control): | |
return control.GetNextSiblingControl() | |
def GetZoomStatus(): | |
global debug | |
global zoomToolbarOpen | |
global zoomMeetingOpen | |
global toggleMute | |
global toggleVideo | |
global toggleView | |
global toggleShare | |
statusMute = "unknown" | |
statusVideo = "unknown" | |
statusShare = "unknown" | |
statusView = "unknown" | |
statusRecord = "unknown" | |
desktop = automation.GetRootControl() | |
if zoomToolbarOpen == True: | |
window = automation.WindowControl(searchDepth=1, ClassName='ZPFloatToolbarClass') | |
toolsMenu = window | |
else: | |
window = automation.WindowControl(searchDepth=1, ClassName='ZPContentViewWndClass') | |
toolsMenu = window.WindowControl(searchDepth=3, ClassName='ZPControlPanelClass') | |
if debug == True: | |
print ("desktop="+str(desktop)) | |
print ("window="+str(window)) | |
print ("toolsMenu="+str(toolsMenu)) | |
if window != toolsMenu: | |
for control, depth in automation.WalkTree(window, getFirstChild=GetFirstChild, getNextSibling=GetNextSibling, includeTop=False, maxDepth=3): | |
if str(control).find("Gallery View (Alt+F2)") > 0: | |
statusView = "speaker" | |
print(str(control)) | |
if toggleView == True: | |
print("sending keys f2") | |
automation.SendKeys('{Alt}{F2}') | |
statusView = "gallery" | |
break | |
elif str(control).find("Speaker View") > 0: | |
statusView = "gallery" | |
if toggleView == True: | |
automation.SendKeys('{Alt}{F1}') | |
statusView = "speaker" | |
break | |
for control, depth in automation.WalkTree(toolsMenu, getFirstChild=GetFirstChild, getNextSibling=GetNextSibling, includeTop=False, maxDepth=2): | |
if debug == True: | |
print(str(depth) + ' ' * depth * 4 + str(control)) | |
if str(control).find("currently muted") > 0: | |
statusMute = "muted" | |
if toggleMute == True: | |
automation.SendKeys('{Alt}a') | |
statusMute = "unmuted" | |
elif str(control).find("currently unmuted") > 0: | |
statusMute = "unmuted" | |
if toggleMute == True: | |
automation.SendKeys('{Alt}a') | |
statusMute = "muted" | |
elif str(control).find("start my video") > 0: | |
statusVideo = "stopped" | |
if toggleVideo == True: | |
automation.SendKeys('{Alt}v') | |
statusVideo = "started" | |
elif str(control).find("stop my video") > 0: | |
statusVideo = "started" | |
if toggleVideo == True: | |
automation.SendKeys('{Alt}v') | |
statusVideo = "stopped" | |
elif str(control).find("Share Screen") > 0: | |
statusShare = "stopped" | |
if toggleShare == True: | |
automation.SendKeys('{Alt}s') | |
statusShare = "started" | |
elif str(control).find("Stop Share") > 0: | |
statusShare = "started" | |
if toggleShare == True: | |
automation.SendKeys('{Alt}s') | |
statusShare = "stopped" | |
elif str(control).find("Resume Share") > 0: | |
statusShare = "disabled" | |
# Toolbar | |
elif str(control).find("Start Video") > 0: | |
statusVideo = "stopped" | |
if toggleVideo == True: | |
automation.SendKeys('{Alt}v') | |
statusVideo = "started" | |
elif str(control).find("Stop Video") > 0: | |
statusVideo = "started" | |
if toggleVideo == True: | |
automation.SendKeys('{Alt}v') | |
statusVideo = "stopped" | |
# The maxDepth needs to be increased if you want to add recording status. However, it doubles the processing time. | |
# elif str(control).find("Name: Record") > 0: | |
# statusRecord = "stopped" | |
# elif str(control).find("Pause/Stop Recording") > 0: | |
# statusRecord = "started" | |
# elif str(control).find("Resume Share") > 0: | |
# statusRecord = "paused" | |
if debug == True: | |
stop = time.time() | |
print("Elapsed Time:", stop-start) | |
statusZoom = "call" | |
status = "zoomStatus:"+statusZoom+",zoomMute:"+statusMute+",zoomVideo:"+statusVideo+",zoomShare:"+statusShare+",zoomView:"+statusView | |
print (status) | |
def end_meeting(): | |
automation.SendKeys('{Alt}q') | |
time.sleep(1) | |
window = automation.WindowControl(searchDepth=1, ClassName='zLeaveWndClass') | |
for control, depth in automation.WalkTree(window, getFirstChild=GetFirstChild, getNextSibling=GetNextSibling, includeTop=False, maxDepth=2): | |
if str(control).find("End Meeting for All") > 0: | |
control.Click(simulateMove = False) | |
exit(0) | |
def main(): | |
if DetectZoomMeeting() == True: | |
# Zoom Meeting in Progress | |
GetZoomStatus() | |
else: | |
# No Zoom Meeting Detected | |
status = "zoomStatus:closed,zoomMute:disabled,zoomVideo:disabled,zoomShare:disabled,zoomView:disabled" | |
print (status) | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser() | |
parser.add_argument("-d", "--debug", help = "Debug", action='store_true') | |
parser.add_argument("-m", "--toggle_mute", help = "Toggle Mute", action='store_true') | |
parser.add_argument("-v", "--toggle_video", help = "Toggle Video", action='store_true') | |
parser.add_argument("-s", "--toggle_share", help = "Toggle Share", action='store_true') | |
parser.add_argument("-t", "--toggle_view", help = "Toggle Speaker View", action='store_true') | |
parser.add_argument("-e", "--end_meeting", help = "End Meeting", action='store_true') | |
args = parser.parse_args() | |
if args.end_meeting: | |
end_meeting() | |
exit(0) | |
if args.debug: | |
debug = True | |
if args.toggle_mute: | |
toggleMute = True | |
if args.toggle_video: | |
toggleVideo = True | |
if args.toggle_share: | |
toggleShare = True | |
if args.toggle_view: | |
toggleView = True | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if window != toolsMenu: | |
for control, depth in automation.WalkTree(window, getFirstChild=GetFirstChild, getNextSibling=GetNextSibling, includeTop=False, maxDepth=3): | |
if str(control).find("Gallery View") > 0: | |
statusView = "speaker" | |
elif str(control).find("Speaker View") > 0: | |
statusView = "gallery" | |
status = "zoomStatus:"+statusZoom+",zoomMute:"+statusMute+",zoomVideo:"+statusVideo+",zoomShare:"+statusShare+",zoomView:"+statusView |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
UIAutomation 2.0.6 (Python 3.7.1, 64 bit) | |
please wait for 3 seconds | |
2020-09-23 23:57:49.005 automation.py[75] main -> Starts, Current Cursor Position: (970, 785) | |
ControlType: PaneControl ClassName: #32769 AutomationId: Rect: (0,0,1536,864)[1536x864] Name: Desktop 1 Handle: 0x10010(65552) Depth: 0 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: WindowControl ClassName: ZPContentViewWndClass AutomationId: Rect: (478,75,1504,811)[1026x736] Name: Zoom Meeting Handle: 0x5045C(328796) Depth: 1 SupportedPattern: LegacyIAccessiblePattern TransformPattern WindowPattern | |
ControlType: ToolTipControl ClassName: tooltips_class32 AutomationId: Rect: (970,799,1051,819)[81x20] Name: Share (Alt+S) Handle: 0x803AE(525230) Depth: 2 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: WindowControl ClassName: ATL:77FACB78 AutomationId: 49697336 Rect: (486,106,1498,804)[1012x698] Name: ContentLeftPanel Handle: 0x80464(525412) Depth: 2 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: WindowControl ClassName: ZPControlPanelClass AutomationId: Rect: (486,751,1498,804)[1012x53] Name: Meeting Tools Handle: 0x203B0(132016) Depth: 3 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: PaneControl ClassName: AutomationId: Rect: (486,751,1498,804)[1012x53] Name: Handle: 0x0(0) Depth: 4 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: PaneControl ClassName: AutomationId: Rect: (486,751,488,804)[2x53] Name: Handle: 0x0(0) Depth: 5 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (488,754,576,802)[88x48] Name: Unmute, currently muted, Alt+A Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: PaneControl ClassName: AutomationId: Rect: (488,754,576,802)[88x48] Name: Handle: 0x0(0) Depth: 6 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: PaneControl ClassName: AutomationId: Rect: (488,754,554,802)[66x48] Name: Handle: 0x0(0) Depth: 7 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: MenuItemControl ClassName: AutomationId: Rect: (554,756,574,782)[20x26] Name: Audio Settings Handle: 0x0(0) Depth: 7 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (576,754,674,802)[98x48] Name: stop my video, Alt+V Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: PaneControl ClassName: AutomationId: Rect: (576,754,674,802)[98x48] Name: Handle: 0x0(0) Depth: 6 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: PaneControl ClassName: AutomationId: Rect: (576,754,652,802)[76x48] Name: Handle: 0x0(0) Depth: 7 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: MenuItemControl ClassName: AutomationId: Rect: (652,756,672,782)[20x26] Name: Video Settingsà Handle: 0x0(0) Depth: 7 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: PaneControl ClassName: AutomationId: Rect: (674,751,692,804)[18x53] Name: Handle: 0x0(0) Depth: 5 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: MenuItemControl ClassName: AutomationId: Rect: (692,754,772,802)[80x48] Name: Security Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (772,754,862,802)[90x48] Name: Closed, open participants pane... Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (862,754,942,802)[80x48] Name: Polls Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (942,754,1040,802)[98x48] Name: Share Screen, Alt+S Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: PaneControl ClassName: AutomationId: Rect: (942,754,1040,802)[98x48] Name: Handle: 0x0(0) Depth: 6 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: PaneControl ClassName: AutomationId: Rect: (942,754,1018,802)[76x48] Name: Handle: 0x0(0) Depth: 7 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: MenuItemControl ClassName: AutomationId: Rect: (1018,756,1038,782)[20x26] Name: Share Option Handle: 0x0(0) Depth: 7 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: MenuItemControl ClassName: AutomationId: Rect: (1041,754,1121,802)[80x48] Name: Record Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (1121,754,1219,802)[98x48] Name: Closed Caption Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: PaneControl ClassName: AutomationId: Rect: (1121,754,1219,802)[98x48] Name: Handle: 0x0(0) Depth: 6 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: PaneControl ClassName: AutomationId: Rect: (1121,754,1219,802)[98x48] Name: Handle: 0x0(0) Depth: 7 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (1218,754,1298,802)[80x48] Name: Reactions Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: MenuItemControl ClassName: AutomationId: Rect: (1298,754,1378,802)[80x48] Name: More meeting controls Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: PaneControl ClassName: AutomationId: Rect: (1378,751,1396,804)[18x53] Name: Handle: 0x0(0) Depth: 5 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (1423,763,1485,791)[62x28] Name: End, Alt+Q Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: PaneControl ClassName: ATL:77FACB78 AutomationId: 49734568 Rect: (910,108,1072,200)[162x92] Name: VideoContainer Handle: 0x203BA(132026) Depth: 3 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: PaneControl ClassName: VideoContainerWndClass AutomationId: 49697624 Rect: (505,202,1479,750)[974x548] Name: VideoContainerWnd Handle: 0x4046E(263278) Depth: 3 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: WindowControl ClassName: VideoRenderWndClass AutomationId: 49698208 Rect: (505,202,1479,750)[974x548] Name: Video Content Handle: 0x701B4(459188) Depth: 4 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (0,0,0,0)[0x0] Name: Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (0,0,0,0)[0x0] Name: Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (513,210,537,234)[24x24] Name: Meeting Information Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (1410,209,1471,235)[61x26] Name: Show my connected time, 00:34:... Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (545,210,569,234)[24x24] Name: You are using enhanced encrypt... Handle: 0x0(0) Depth: 5 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (1463,113,1489,139)[26x26] Name: Enter Full Screen (Alt+F) Handle: 0x0(0) Depth: 3 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (1354,112,1455,138)[101x26] Name: Gallery View (Alt+F2) Handle: 0x0(0) Depth: 3 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: TitleBarControl ClassName: AutomationId: Rect: (502,78,1498,106)[996x28] Name: Handle: 0x0(0) Depth: 2 ValuePattern.Value: Zoom Meeting SupportedPattern: LegacyIAccessiblePattern ValuePattern | |
ControlType: MenuBarControl ClassName: AutomationId: MenuBar Rect: (486,82,508,104)[22x22] Name: System Handle: 0x0(0) Depth: 3 SupportedPattern: LegacyIAccessiblePattern | |
ControlType: MenuItemControl ClassName: AutomationId: Rect: (486,82,508,104)[22x22] Name: System Handle: 0x0(0) Depth: 4 ExpandCollapsePattern.ExpandCollapseState: ExpandCollapseState.Collapsed SupportedPattern: ExpandCollapsePattern InvokePattern LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (1355,76,1403,106)[48x30] Name: Minimize Handle: 0x0(0) Depth: 3 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (1403,76,1450,106)[47x30] Name: Maximize Handle: 0x0(0) Depth: 3 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
ControlType: ButtonControl ClassName: AutomationId: Rect: (1450,76,1498,106)[48x30] Name: Close Handle: 0x0(0) Depth: 3 SupportedPattern: InvokePattern LegacyIAccessiblePattern | |
2020-09-23 23:58:05.960 automation.py[110] main -> Ends | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment