├── README.md └── src ├── AutomationSpy.sln ├── AutomationSpy ├── AboutForm.Designer.cs ├── AboutForm.cs ├── AboutForm.resx ├── Actions.cs ├── App.config ├── App.xaml ├── App.xaml.cs ├── AutomationSpy.Cache.cs ├── AutomationSpy.ControlPatterns.cs ├── AutomationSpy.Current.cs ├── AutomationSpy.csproj ├── AutomationSpy.csproj.user ├── Defines.cs ├── Event.cs ├── Helper.cs ├── Lib │ └── Interop.UIAutomationClient.dll ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── MoreAttributes.xaml ├── MoreAttributes.xaml.cs ├── Pictures │ ├── 28x28xHighlight.png │ ├── 28x28xHighlightPressed.png │ ├── 30x30xautomationspy.png │ ├── 32x32actions.png │ ├── 32x32xPointer.png │ ├── 32x32xPointerPressed.png │ ├── 32x32xabout.png │ ├── 32x32xrefresh.png │ ├── Play.png │ ├── Stop.png │ ├── appicon.ico │ ├── evProp.png │ ├── options.png │ └── sigla-32x32.png ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── PropertySettings.xaml ├── PropertySettings.xaml.cs ├── WindowActions.xaml ├── WindowActions.xaml.cs ├── WindowAllText.xaml ├── WindowAllText.xaml.cs ├── WindowEventsOptions.xaml ├── WindowEventsOptions.xaml.cs └── appicon.ico └── build-release.cmd /README.md: -------------------------------------------------------------------------------- 1 | # Automation Spy 2 | Automation Spy is a spy utility tool designed to inspect Microsoft UI Automation hierarchy of elements. 3 | 4 | This tool has simple intuitive features and buttons that can be used to work with it. Can be used to navigate through MS UI Automation hierarchy of objects and inspect for properties and control patterns of each object. You can directly navigate to an element using the mouse pointer. You can also monitor UI Automation events that are raised for a specific element. Additionally, you can make actions on Automation elements using control patterns. Why Automation Spy? Because we want to make it easy to develop applications using Microsoft UI Automation technology (UIA). 5 | 6 | It is built using the unmanaged version of UI Automation API (UIA or Windows Automation API 3.0). Located in Windows\System32\UIAutomationCore.dll, Windows Automation API 3.0 library is the latest version of UI Automation, was introduced starting with Windows 7 and was written as a Component Object Model (COM). This tool is freeware. Requirements: Windows 7 or later, .NET Framework 4.0 or later. 7 | 8 | You can download the latest release from here: https://github.com/ddeltasolutions/Automation-Spy/releases 9 | 10 | Screenshot:
11 | ![image](https://user-images.githubusercontent.com/24210619/164229746-d14c433e-edc1-498d-8a51-1aea0b9d275d.png) 12 | 13 | Note: If you have trouble with opening this program, right click the .exe file, choose Properties from the menu and in the lower part of the Properties dialog box you can see an "Unblock" checkbox. Check it and press Apply and OK. 14 | -------------------------------------------------------------------------------- /src/AutomationSpy.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Express 2013 for Windows Desktop 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutomationSpy", "AutomationSpy\AutomationSpy.csproj", "{3549AB3D-03CD-4CAB-8CFD-949029F4101B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3549AB3D-03CD-4CAB-8CFD-949029F4101B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {3549AB3D-03CD-4CAB-8CFD-949029F4101B}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {3549AB3D-03CD-4CAB-8CFD-949029F4101B}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {3549AB3D-03CD-4CAB-8CFD-949029F4101B}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /src/AutomationSpy/AboutForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace dDeltaSolutions.Spy 2 | { 3 | partial class AboutForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutForm)); 32 | this.closeButton = new System.Windows.Forms.Button(); 33 | this.label1 = new System.Windows.Forms.Label(); 34 | this.label2 = new System.Windows.Forms.Label(); 35 | this.label3 = new System.Windows.Forms.Label(); 36 | this.textBox1 = new System.Windows.Forms.TextBox(); 37 | this.versionLabel = new System.Windows.Forms.Label(); 38 | this.pictureBox1 = new System.Windows.Forms.PictureBox(); 39 | this.pictureBox2 = new System.Windows.Forms.PictureBox(); 40 | this.label5 = new System.Windows.Forms.Label(); 41 | this.linkLabel1 = new System.Windows.Forms.LinkLabel(); 42 | this.label4 = new System.Windows.Forms.Label(); 43 | this.whatsNewTextBox = new System.Windows.Forms.TextBox(); 44 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 45 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit(); 46 | this.SuspendLayout(); 47 | // 48 | // closeButton 49 | // 50 | this.closeButton.Location = new System.Drawing.Point(197, 275); 51 | this.closeButton.Name = "closeButton"; 52 | this.closeButton.Size = new System.Drawing.Size(75, 23); 53 | this.closeButton.TabIndex = 0; 54 | this.closeButton.Text = "Close"; 55 | this.closeButton.UseVisualStyleBackColor = true; 56 | this.closeButton.Click += new System.EventHandler(this.closeButton_Click); 57 | // 58 | // label1 59 | // 60 | this.label1.AutoSize = true; 61 | this.label1.Location = new System.Drawing.Point(93, 13); 62 | this.label1.Name = "label1"; 63 | this.label1.Size = new System.Drawing.Size(81, 13); 64 | this.label1.TabIndex = 1; 65 | this.label1.Text = MainWindow.AppName; 66 | // 67 | // label2 68 | // 69 | this.label2.AutoSize = true; 70 | this.label2.Location = new System.Drawing.Point(57, 69); 71 | this.label2.Name = "label2"; 72 | this.label2.Size = new System.Drawing.Size(159, 13); 73 | this.label2.TabIndex = 2; 74 | this.label2.Text = "©2014 - 2024 - dDelta Solutions"; 75 | // 76 | // label3 77 | // 78 | this.label3.AutoSize = true; 79 | this.label3.Location = new System.Drawing.Point(57, 188); 80 | this.label3.Name = "label3"; 81 | this.label3.Size = new System.Drawing.Size(185, 13); 82 | this.label3.TabIndex = 4; 83 | this.label3.Text = "For any kind of issues please contact:"; 84 | // 85 | // textBox1 86 | // 87 | this.textBox1.Location = new System.Drawing.Point(60, 204); 88 | this.textBox1.Name = "textBox1"; 89 | this.textBox1.ReadOnly = true; 90 | this.textBox1.Size = new System.Drawing.Size(182, 20); 91 | this.textBox1.TabIndex = 5; 92 | this.textBox1.Text = "daniel.mocanu072180@gmail.com"; 93 | // 94 | // versionLabel 95 | // 96 | this.versionLabel.AutoSize = true; 97 | this.versionLabel.Location = new System.Drawing.Point(94, 30); 98 | this.versionLabel.Name = "versionLabel"; 99 | this.versionLabel.Size = new System.Drawing.Size(47, 13); 100 | this.versionLabel.TabIndex = 6; 101 | this.versionLabel.Text = "version: "; 102 | // 103 | // pictureBox1 104 | // 105 | this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image"))); 106 | this.pictureBox1.InitialImage = ((System.Drawing.Image)(resources.GetObject("pictureBox1.InitialImage"))); 107 | this.pictureBox1.Location = new System.Drawing.Point(221, 50); 108 | this.pictureBox1.Name = "pictureBox1"; 109 | this.pictureBox1.Size = new System.Drawing.Size(32, 32); 110 | this.pictureBox1.TabIndex = 3; 111 | this.pictureBox1.TabStop = false; 112 | // 113 | // pictureBox2 114 | // 115 | this.pictureBox2.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox2.Image"))); 116 | this.pictureBox2.Location = new System.Drawing.Point(60, 13); 117 | this.pictureBox2.Name = "pictureBox2"; 118 | this.pictureBox2.Size = new System.Drawing.Size(30, 30); 119 | this.pictureBox2.TabIndex = 7; 120 | this.pictureBox2.TabStop = false; 121 | // 122 | // label5 123 | // 124 | this.label5.AutoSize = true; 125 | this.label5.Location = new System.Drawing.Point(57, 233); 126 | this.label5.Name = "label5"; 127 | this.label5.Size = new System.Drawing.Size(160, 13); 128 | this.label5.TabIndex = 8; 129 | this.label5.Text = "For more information please visit:"; 130 | // 131 | // linkLabel1 132 | // 133 | this.linkLabel1.AutoSize = true; 134 | this.linkLabel1.Location = new System.Drawing.Point(57, 249); 135 | this.linkLabel1.Name = "linkLabel1"; 136 | this.linkLabel1.Size = new System.Drawing.Size(215, 13); 137 | this.linkLabel1.TabIndex = 9; 138 | this.linkLabel1.TabStop = true; 139 | this.linkLabel1.Text = "http://automationspy.freecluster.eu/"; 140 | this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabel1_LinkClicked); 141 | // 142 | // label4 143 | // 144 | this.label4.AutoSize = true; 145 | this.label4.Location = new System.Drawing.Point(20, 91); 146 | this.label4.Name = "label4"; 147 | this.label4.Size = new System.Drawing.Size(66, 13); 148 | this.label4.TabIndex = 10; 149 | this.label4.Text = "About:"; 150 | // 151 | // whatsNewTextBox 152 | // 153 | this.whatsNewTextBox.Location = new System.Drawing.Point(20, 107); 154 | this.whatsNewTextBox.Multiline = true; 155 | this.whatsNewTextBox.Name = "whatsNewTextBox"; 156 | this.whatsNewTextBox.ReadOnly = true; 157 | this.whatsNewTextBox.Size = new System.Drawing.Size(287, 72); 158 | this.whatsNewTextBox.TabIndex = 11; 159 | this.whatsNewTextBox.Text = "This spy is using the unmanaged version of UI Automation API. Located in Windows\\System32\\UIAutomationCore.dll, Windows Automation API 3.0 came starting with Windows 7 and was written as a Component Object Model (COM). The unmanaged library is newer than the managed library."; 160 | // 161 | // AboutForm 162 | // 163 | this.CancelButton = this.closeButton; 164 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 165 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 166 | this.ClientSize = new System.Drawing.Size(329, 318); 167 | this.Controls.Add(this.whatsNewTextBox); 168 | this.Controls.Add(this.label4); 169 | this.Controls.Add(this.linkLabel1); 170 | this.Controls.Add(this.label5); 171 | this.Controls.Add(this.pictureBox2); 172 | this.Controls.Add(this.versionLabel); 173 | this.Controls.Add(this.textBox1); 174 | this.Controls.Add(this.label3); 175 | this.Controls.Add(this.pictureBox1); 176 | this.Controls.Add(this.label2); 177 | this.Controls.Add(this.label1); 178 | this.Controls.Add(this.closeButton); 179 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; 180 | this.MaximizeBox = false; 181 | this.MinimizeBox = false; 182 | this.Name = "AboutForm"; 183 | this.ShowInTaskbar = false; 184 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 185 | this.Text = "About"; 186 | this.Load += new System.EventHandler(this.AboutForm_Load); 187 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 188 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit(); 189 | this.ResumeLayout(false); 190 | this.PerformLayout(); 191 | 192 | } 193 | 194 | #endregion 195 | 196 | private System.Windows.Forms.Button closeButton; 197 | private System.Windows.Forms.Label label1; 198 | private System.Windows.Forms.Label label2; 199 | private System.Windows.Forms.PictureBox pictureBox1; 200 | private System.Windows.Forms.Label label3; 201 | private System.Windows.Forms.TextBox textBox1; 202 | private System.Windows.Forms.Label versionLabel; 203 | private System.Windows.Forms.PictureBox pictureBox2; 204 | private System.Windows.Forms.Label label5; 205 | private System.Windows.Forms.LinkLabel linkLabel1; 206 | private System.Windows.Forms.Label label4; 207 | private System.Windows.Forms.TextBox whatsNewTextBox; 208 | } 209 | } -------------------------------------------------------------------------------- /src/AutomationSpy/AboutForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Diagnostics; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Windows.Forms; 10 | 11 | namespace dDeltaSolutions.Spy 12 | { 13 | public partial class AboutForm : Form 14 | { 15 | public AboutForm() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | private void closeButton_Click(object sender, EventArgs e) 21 | { 22 | this.Close(); 23 | } 24 | 25 | private void AboutForm_Load(object sender, EventArgs e) 26 | { 27 | this.versionLabel.Text += MainWindow.Version; 28 | } 29 | 30 | private void LinkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 31 | { 32 | Process.Start(linkLabel1.Text); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/AutomationSpy/AboutForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | 123 | Qk02DAAAAAAAADYAAAAoAAAAIAAAACAAAAABABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////// 124 | //////////////////////////////////////////////////////////////////////////////// 125 | //////////////////////////////////////////////////////////////////////////////// 126 | //////////////////////////////////////////////////////////////////////////////// 127 | //////////////////////////////////////////////////////////////////////////////// 128 | //////////////////////////////////////////////////////////////////////////////// 129 | //////////////////////////////////////////////////////////////////////////////// 130 | //////////////////////////////////////////////////////////////////////////////// 131 | //////////////////////////////////////////////////////////////////////////////// 132 | //////////////////////////////////////////////////////////////////////////////// 133 | //////////////////////////////////////////////////////////////////////////////// 134 | /////////////////////////////////////////////////////////////v39//////////////// 135 | ////////////////EBYeAAAAJB8aW2JmpJiP////////nzpEngAAmgAAmgAAmgAAqhwbxWRg8eXh//// 136 | ////////////////wHZ7mAABjQAAjgAAjwAAsjgz+PHs////////////////Xmp1QDUp////8vj+AAAA 137 | p5uS////////jxQemwAAxmhnw19fwF1frCkrjwAAkQAAw2Na////////////sn2JiwAAricj1I2K3aWl 138 | vGZrkQAAjwAA9eri////////////FyMuuK2i////////PUxVoZSL////////kRgjmAAA//////////// 139 | ////+v//miEplQAAx3No////////2sHH787H////////////////z87amAAArS8l////////////GSUw 140 | ua6j////////PUtVoZSL////////kRgjmAAA////////////////////////jQAAkwAA/P31//////// 141 | ////////////////////////hAAAlwAA////////////bnqGNioe////+f//AAAAqJyT////////kRgj 142 | mAAA////////////////////////uYWQlgAAz4qA////////////////////////////7///kQAAmQAA 143 | ////////////////JSw0AAAAGhQQKzI3pJiP////////kRgjmAAA////////////////////////187X 144 | lQAAt0k/////////////////////////6uTplgYKmAAAvlpP////////////////////////////OUdR 145 | oZSL////////kRgjmAAA////////////////////////3+33lQAAsC0j////////////////3dDWpC0y 146 | kwAAlAAArScf////////////////tvv/avf/////////KzlDm46E////////kRgjmAAA//////////// 147 | ////////////3uv2lQAArysh////////////pD5GlAAAlAAApAwI37Gr////////////////////svr/ 148 | bPf/////////lp2i0crF////////kRgjmAAA////////////////////////1MbPlgAAtkk///////// 149 | o0xYmQAAngAA5MO9////////////////////////////ufz/LOj/////////////////////////kRgj 150 | mAAA////////////////////////q2VvlgAA0Y+F////8v//jgAAmgAA//////////////////////// 151 | ////////////ufz/Ouv/////////////////////////kRgjmAAA////////////////////6/b9jwAA 152 | lAAA////////5PH7lgAAskA2////////////////////////////////////wf7/ANX///////////// 153 | ////////////kRgjmAAA////////////////1bW8kQAAkgAA1Z6S////////////hQAAmgAA//////// 154 | ////////xpCW+fHr////////////wf7/ANf/////////////////////////jA4YmgAAqBYWpxISog8Q 155 | kAAAkQAAlAAA26Ka////////////////xqq0jwAAlAAAvk9NvE9QkQAAhwAA8eDT////////////wf7/ 156 | ANf/////////////////////////vHh/uDw8tz09tz09tjo7xWJf2aCe//////////////////////// 157 | ////5dTZsUFEnQAAnwAAuD475r+5////////////////wf7/ANf///////////////////////////// 158 | //////////////////////////////////////////////////////////////////////////////// 159 | ////////////wf7/ANf///////////////////////////////////////////////////////////// 160 | ////////////////////////////////////////////////////////////wf7/ANf///////////// 161 | //////////////////////////////////////////////////////////////////////////////// 162 | ////////////////////////////wf7/ANf///////////////////////////////////////////// 163 | ////////////////////////////////////////////////////////////////////////////wf7/ 164 | ANf/q+X/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/ 165 | muT/luP/xu7/y+////v/0vH/uuz/////////////////u/v/AOr/AOD/AOH/AOH/AOH/AOH/AOH/AOH/ 166 | AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOj/AOn/GPD/AOr/AOb///// 167 | //////////////////////////////////////////////////////////////////////////////// 168 | //////////////////////////////////////////////////////////////////////////////// 169 | //////////////////////////////////////////////////////////////////////////////// 170 | //////////////////////////////////////////////////////////////////////////////// 171 | //////////////////////////////////////////////////////////////////////////////// 172 | //////////////////////////////////////////////////////////////////////////////// 173 | //////////////////////////////////////////////////////////////////////////////// 174 | //////////////////////////////////////////////////////////////////////////////// 175 | //////// 176 | 177 | 178 | 179 | 180 | Qk02DAAAAAAAADYAAAAoAAAAIAAAACAAAAABABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////// 181 | //////////////////////////////////////////////////////////////////////////////// 182 | //////////////////////////////////////////////////////////////////////////////// 183 | //////////////////////////////////////////////////////////////////////////////// 184 | //////////////////////////////////////////////////////////////////////////////// 185 | //////////////////////////////////////////////////////////////////////////////// 186 | //////////////////////////////////////////////////////////////////////////////// 187 | //////////////////////////////////////////////////////////////////////////////// 188 | //////////////////////////////////////////////////////////////////////////////// 189 | //////////////////////////////////////////////////////////////////////////////// 190 | //////////////////////////////////////////////////////////////////////////////// 191 | /////////////////////////////////////////////////////////////v39//////////////// 192 | ////////////////EBYeAAAAJB8aW2JmpJiP////////nzpEngAAmgAAmgAAmgAAqhwbxWRg8eXh//// 193 | ////////////////wHZ7mAABjQAAjgAAjwAAsjgz+PHs////////////////Xmp1QDUp////8vj+AAAA 194 | p5uS////////jxQemwAAxmhnw19fwF1frCkrjwAAkQAAw2Na////////////sn2JiwAAricj1I2K3aWl 195 | vGZrkQAAjwAA9eri////////////FyMuuK2i////////PUxVoZSL////////kRgjmAAA//////////// 196 | ////+v//miEplQAAx3No////////2sHH787H////////////////z87amAAArS8l////////////GSUw 197 | ua6j////////PUtVoZSL////////kRgjmAAA////////////////////////jQAAkwAA/P31//////// 198 | ////////////////////////hAAAlwAA////////////bnqGNioe////+f//AAAAqJyT////////kRgj 199 | mAAA////////////////////////uYWQlgAAz4qA////////////////////////////7///kQAAmQAA 200 | ////////////////JSw0AAAAGhQQKzI3pJiP////////kRgjmAAA////////////////////////187X 201 | lQAAt0k/////////////////////////6uTplgYKmAAAvlpP////////////////////////////OUdR 202 | oZSL////////kRgjmAAA////////////////////////3+33lQAAsC0j////////////////3dDWpC0y 203 | kwAAlAAArScf////////////////tvv/avf/////////KzlDm46E////////kRgjmAAA//////////// 204 | ////////////3uv2lQAArysh////////////pD5GlAAAlAAApAwI37Gr////////////////////svr/ 205 | bPf/////////lp2i0crF////////kRgjmAAA////////////////////////1MbPlgAAtkk///////// 206 | o0xYmQAAngAA5MO9////////////////////////////ufz/LOj/////////////////////////kRgj 207 | mAAA////////////////////////q2VvlgAA0Y+F////8v//jgAAmgAA//////////////////////// 208 | ////////////ufz/Ouv/////////////////////////kRgjmAAA////////////////////6/b9jwAA 209 | lAAA////////5PH7lgAAskA2////////////////////////////////////wf7/ANX///////////// 210 | ////////////kRgjmAAA////////////////1bW8kQAAkgAA1Z6S////////////hQAAmgAA//////// 211 | ////////xpCW+fHr////////////wf7/ANf/////////////////////////jA4YmgAAqBYWpxISog8Q 212 | kAAAkQAAlAAA26Ka////////////////xqq0jwAAlAAAvk9NvE9QkQAAhwAA8eDT////////////wf7/ 213 | ANf/////////////////////////vHh/uDw8tz09tz09tjo7xWJf2aCe//////////////////////// 214 | ////5dTZsUFEnQAAnwAAuD475r+5////////////////wf7/ANf///////////////////////////// 215 | //////////////////////////////////////////////////////////////////////////////// 216 | ////////////wf7/ANf///////////////////////////////////////////////////////////// 217 | ////////////////////////////////////////////////////////////wf7/ANf///////////// 218 | //////////////////////////////////////////////////////////////////////////////// 219 | ////////////////////////////wf7/ANf///////////////////////////////////////////// 220 | ////////////////////////////////////////////////////////////////////////////wf7/ 221 | ANf/q+X/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/muT/ 222 | muT/luP/xu7/y+////v/0vH/uuz/////////////////u/v/AOr/AOD/AOH/AOH/AOH/AOH/AOH/AOH/ 223 | AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOj/AOn/GPD/AOr/AOb///// 224 | //////////////////////////////////////////////////////////////////////////////// 225 | //////////////////////////////////////////////////////////////////////////////// 226 | //////////////////////////////////////////////////////////////////////////////// 227 | //////////////////////////////////////////////////////////////////////////////// 228 | //////////////////////////////////////////////////////////////////////////////// 229 | //////////////////////////////////////////////////////////////////////////////// 230 | //////////////////////////////////////////////////////////////////////////////// 231 | //////////////////////////////////////////////////////////////////////////////// 232 | //////// 233 | 234 | 235 | 236 | 237 | iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO 238 | vAAADrwBlbxySQAAAVJJREFUSEvtlcsRwjAMRNMN/VANN6rgRgfpgRma4EoBFGHkRHLWzgZ/SMiFndFM 239 | cBw/eS2Zzu2kP3jS4+Tc+aAhz6gwXhmgZXCffPTQ8VaVgW8KlJ3ej+Pz5arvGlUENpt7SeAlwCEJSeCl 240 | 71tUBDabB3ufslv9fZfnVmXBYYdQUGvZDZqDDeJtNoVkJL4tMlUCBlsjAIxjQlQwFyNxKwYzm03mBHtn 241 | inqfxfRtDLaioruyFpNgduNxsFoY1qbgzMJenxIrcQQ0gbM2YZCebganV2Qu0p4OYJIUkYILbDZZguk5 242 | 4hkXwEdwjU3hSMjiYR2L5fUEXNOjXuAOm09rZZ5A13QrhXr44NBs9xJQF11tNQ7CXeWSTRPQ+VNVbyly 243 | ufwG7JUczwj2A1trH/C8c1YCW4uxAoX28xEV12rgTETt5MUmlQZq6b4nf5MjeAftBHbuDesw5Q98uU59 244 | AAAAAElFTkSuQmCC 245 | 246 | 247 | -------------------------------------------------------------------------------- /src/AutomationSpy/Actions.cs: -------------------------------------------------------------------------------- 1 | 2 | using System.Windows; 3 | using System.Windows.Controls; 4 | 5 | namespace dDeltaSolutions.Spy 6 | { 7 | public partial class MainWindow 8 | { 9 | private void OnActions(object sender, RoutedEventArgs e) 10 | { 11 | TreeViewItem treeviewItem = this.tvElements.SelectedItem as TreeViewItem; 12 | if (treeviewItem == null) 13 | { 14 | System.Windows.MessageBox.Show("Select an element in the tree"); 15 | return; 16 | } 17 | 18 | TreeNode node = treeviewItem.Tag as TreeNode; 19 | if (node == null) 20 | { 21 | return; 22 | } 23 | 24 | if (node.IsAlive == false) 25 | { 26 | System.Windows.MessageBox.Show("The selected element is not available anymore"); 27 | return; 28 | } 29 | 30 | bool timerStopped = false; 31 | if (timer != null && timer.Enabled == true) 32 | { 33 | timer.Enabled = false; 34 | timerStopped = true; 35 | } 36 | 37 | bool timerTrackStopped = false; 38 | if (timerTrack != null && timerTrack.Enabled == true) 39 | { 40 | timerTrack.Enabled = false; 41 | timerTrackStopped = true; 42 | } 43 | 44 | WindowActions wndActions = new WindowActions(node); 45 | wndActions.Owner = this; 46 | wndActions.ShowDialog(); 47 | 48 | if (timerStopped == true) 49 | { 50 | timer.Enabled = true; 51 | } 52 | 53 | if (timerTrackStopped == true) 54 | { 55 | timerTrack.Enabled = true; 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /src/AutomationSpy/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/AutomationSpy/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/AutomationSpy/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Windows; 7 | 8 | namespace Spy 9 | { 10 | /// 11 | /// Interaction logic for App.xaml 12 | /// 13 | public partial class App : Application 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutomationSpy/AutomationSpy.Cache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using System.Diagnostics; 4 | using Interop.UIAutomationClient; 5 | 6 | namespace dDeltaSolutions.Spy 7 | { 8 | public partial class MainWindow 9 | { 10 | private void GetCachedInformation(TreeNode node) 11 | { 12 | if (PropertySettings.hasAcceleratorKey == true) 13 | { 14 | try 15 | { 16 | string acceleratorKey = "\"" + node.Element.CachedAcceleratorKey + "\""; 17 | Attribute attribute = new Attribute("Accelerator Key:", acceleratorKey); 18 | attribute.Tooltip = "String containing the accelerator key combinations for the element"; 19 | this.listAttributes.Add(attribute); 20 | } 21 | catch { } 22 | } 23 | 24 | if (PropertySettings.hasAccessKey == true) 25 | { 26 | try 27 | { 28 | string accessKey = "\"" + node.Element.CachedAccessKey + "\""; 29 | Attribute attribute = new Attribute("Access Key:", accessKey); 30 | attribute.Tooltip = "String containing the access key character for the element"; 31 | this.listAttributes.Add(attribute); 32 | } 33 | catch { } 34 | } 35 | 36 | if (PropertySettings.hasAriaProperties == true) 37 | { 38 | try 39 | { 40 | string ariaProperties = "\"" + node.Element.CachedAriaProperties + "\""; 41 | Attribute attribute = new Attribute("Aria Properties:", ariaProperties); 42 | attribute.Tooltip = "Accessible Rich Internet Applications (ARIA) properties of the element"; 43 | this.listAttributes.Add(attribute); 44 | } 45 | catch { } 46 | } 47 | 48 | if (PropertySettings.hasAriaRole == true) 49 | { 50 | try 51 | { 52 | string ariaRole = "\"" + node.Element.CachedAriaRole + "\""; 53 | Attribute attribute = new Attribute("Aria Role:", ariaRole); 54 | attribute.Tooltip = "Accessible Rich Internet Applications (ARIA) role of the element"; 55 | this.listAttributes.Add(attribute); 56 | } 57 | catch { } 58 | } 59 | 60 | //get automation id 61 | if (PropertySettings.hasAutomationId == true) 62 | { 63 | try 64 | { 65 | string automationIdString = "\"" + node.Element.CachedAutomationId + "\""; 66 | Attribute attribute = new Attribute("AutomationId:", automationIdString); 67 | attribute.Tooltip = "String containing the UI Automation identifier (ID) for the element"; 68 | this.listAttributes.Add(attribute); 69 | } 70 | catch { } 71 | } 72 | 73 | //get bounding rectangle 74 | if (PropertySettings.hasBoundingRectangle == true) 75 | { 76 | try 77 | { 78 | tagRECT boundingRectangle = node.Element.CachedBoundingRectangle; 79 | string rectangleString = RectangleToString(boundingRectangle); 80 | Attribute attribute = new Attribute("Bounding rectangle:", rectangleString); 81 | attribute.Tooltip = "Coordinates of the rectangle that completely encloses the element"; 82 | this.listAttributes.Add(attribute); 83 | } 84 | catch { } 85 | } 86 | 87 | //get window class 88 | if (PropertySettings.hasClassName == true) 89 | { 90 | try 91 | { 92 | string windowClass = "\"" + node.Element.CachedClassName + "\""; 93 | Attribute attribute = new Attribute("Class Name:", windowClass); 94 | attribute.Tooltip = "String containing the class name of the element as assigned by the control developer"; 95 | this.listAttributes.Add(attribute); 96 | } 97 | catch { } 98 | } 99 | 100 | // clickable point 101 | if (PropertySettings.hasClickablePoint == true) 102 | { 103 | try 104 | { 105 | object clickablePointObj = node.Element.GetCachedPropertyValue(UIA_PropertyIds.UIA_ClickablePointPropertyId); 106 | if (clickablePointObj != null) 107 | { 108 | tagPOINT clickablePoint = (tagPOINT)clickablePointObj; 109 | string pointString = GetStringFromPoint(clickablePoint); 110 | Attribute attribute = new Attribute("ClickablePoint:", pointString); 111 | attribute.Tooltip = "Point on the Automation Element that could be clicked"; 112 | this.listAttributes.Add(attribute); 113 | } 114 | } 115 | catch (Exception ex) 116 | { } 117 | } 118 | 119 | if (PropertySettings.hasControllerFor == true) 120 | { 121 | try 122 | { 123 | IUIAutomationElementArray array = node.Element.CachedControllerFor; 124 | for (int i = 0; i < array.Length; i++) 125 | { 126 | IUIAutomationElement element = array.GetElement(i); 127 | TreeNode elementNode = new TreeNode(element); 128 | string controllerForString = elementNode.ToString(); 129 | Attribute attribute = new Attribute("ControllerFor[" + i + "]:", controllerForString); 130 | attribute.Tooltip = "Array of elements for which this element served as the controller"; 131 | attribute.UnderneathElement = element; 132 | this.listAttributes.Add(attribute); 133 | } 134 | } 135 | catch {} 136 | } 137 | 138 | //get Control Type 139 | if (PropertySettings.hasControlType == true) 140 | { 141 | try 142 | { 143 | int controlTypeId = node.Element.CachedControlType; 144 | string controlTypeString = Helper.ControlTypeIdToString(controlTypeId) + " (" + controlTypeId + ")"; 145 | Attribute attribute = new Attribute("Control type:", controlTypeString); 146 | attribute.Tooltip = "Control type of the element"; 147 | this.listAttributes.Add(attribute); 148 | } 149 | catch { } 150 | } 151 | 152 | if (PropertySettings.hasCulture == true) 153 | { 154 | try 155 | { 156 | int culture = node.Element.CachedCulture; 157 | Attribute attribute = new Attribute("Culture:", culture.ToString()); 158 | attribute.Tooltip = "Culture identifier"; 159 | this.listAttributes.Add(attribute); 160 | } 161 | catch { } 162 | } 163 | 164 | if (PropertySettings.hasDescribedBy == true) 165 | { 166 | try 167 | { 168 | IUIAutomationElementArray array = node.Element.CachedDescribedBy; 169 | for (int i = 0; i < array.Length; i++) 170 | { 171 | IUIAutomationElement element = array.GetElement(i); 172 | TreeNode elementNode = new TreeNode(element); 173 | string describedByString = elementNode.ToString(); 174 | Attribute attribute = new Attribute("DescribedBy[" + i + "]:", describedByString); 175 | attribute.Tooltip = "Array of elements that describe this element"; 176 | attribute.UnderneathElement = element; 177 | this.listAttributes.Add(attribute); 178 | } 179 | } 180 | catch {} 181 | } 182 | 183 | if (PropertySettings.hasFlowsTo == true) 184 | { 185 | try 186 | { 187 | IUIAutomationElementArray array = node.Element.CachedFlowsTo; 188 | for (int i = 0; i < array.Length; i++) 189 | { 190 | IUIAutomationElement element = array.GetElement(i); 191 | TreeNode elementNode = new TreeNode(element); 192 | string flowsToString = elementNode.ToString(); 193 | Attribute attribute = new Attribute("FlowsTo[" + i + "]:", flowsToString); 194 | attribute.Tooltip = "Array of elements that indicates the reading order after the current element"; 195 | attribute.UnderneathElement = element; 196 | this.listAttributes.Add(attribute); 197 | } 198 | } 199 | catch {} 200 | } 201 | 202 | if (PropertySettings.hasFrameworkId == true) 203 | { 204 | try 205 | { 206 | string frameworkIdString = node.Element.CachedFrameworkId; 207 | Attribute attribute = new Attribute("FrameworkId:", "\"" + frameworkIdString + "\""); 208 | attribute.Tooltip = "Name of the underlying UI framework"; 209 | this.listAttributes.Add(attribute); 210 | } 211 | catch { } 212 | } 213 | 214 | if (PropertySettings.hasHasKeyboardFocus == true) 215 | { 216 | try 217 | { 218 | int hasKeyboboardFocus = node.Element.CachedHasKeyboardFocus; 219 | Attribute attribute = new Attribute("HasKeyboardFocus:", hasKeyboboardFocus.ToString()); 220 | attribute.Tooltip = "Value that indicates whether the element had keyboard focus"; 221 | this.listAttributes.Add(attribute); 222 | } 223 | catch { } 224 | } 225 | 226 | if (PropertySettings.hasHelpText == true) 227 | { 228 | try 229 | { 230 | string helpText = "\"" + node.Element.CachedHelpText + "\""; 231 | Attribute attribute = new Attribute("Help Text:", helpText); 232 | attribute.Tooltip = "Help text associated with the element"; 233 | this.listAttributes.Add(attribute); 234 | } 235 | catch { } 236 | } 237 | 238 | if (PropertySettings.hasIsContentElement == true) 239 | { 240 | try 241 | { 242 | string isContentString = node.Element.CachedIsContentElement.ToString(); 243 | Attribute attribute = new Attribute("IsContentElement:", isContentString); 244 | attribute.Tooltip = "Value that specifies whether the element is a content element"; 245 | this.listAttributes.Add(attribute); 246 | } 247 | catch { } 248 | } 249 | 250 | if (PropertySettings.hasIsControlElement == true) 251 | { 252 | try 253 | { 254 | string isControlString = node.Element.CachedIsControlElement.ToString(); 255 | Attribute attribute = new Attribute("IsControlElement:", isControlString); 256 | attribute.Tooltip = "Value that indicates whether the element is viewed as a control"; 257 | this.listAttributes.Add(attribute); 258 | } 259 | catch { } 260 | } 261 | 262 | if (PropertySettings.hasIsDataValidForForm == true) 263 | { 264 | try 265 | { 266 | string isDataValidForFormString = node.Element.CachedIsDataValidForForm.ToString(); 267 | Attribute attribute = new Attribute("IsDataValidForForm:", isDataValidForFormString); 268 | attribute.Tooltip = "Indicates whether the element contains valid data for a form"; 269 | this.listAttributes.Add(attribute); 270 | } 271 | catch { } 272 | } 273 | 274 | if (PropertySettings.hasIsEnabled == true) 275 | { 276 | try 277 | { 278 | string isEnabledString = node.Element.CachedIsEnabled.ToString(); 279 | Attribute attribute = new Attribute("IsEnabled:", isEnabledString); 280 | attribute.Tooltip = "Value that indicates whether the element is enabled"; 281 | this.listAttributes.Add(attribute); 282 | } 283 | catch { } 284 | } 285 | 286 | if (PropertySettings.hasIsKeyboardFocusable == true) 287 | { 288 | try 289 | { 290 | string isKeyboardFocusableString = node.Element.CachedIsKeyboardFocusable.ToString(); 291 | Attribute attribute = new Attribute("IsKeyboardFocusable:", isKeyboardFocusableString); 292 | attribute.Tooltip = "Value that indicates whether the UI Automation element can accept keyboard focus"; 293 | this.listAttributes.Add(attribute); 294 | } 295 | catch { } 296 | } 297 | 298 | if (PropertySettings.hasIsOffscreen == true) 299 | { 300 | try 301 | { 302 | string isOffscreenString = node.Element.CachedIsOffscreen.ToString(); 303 | Attribute attribute = new Attribute("IsOffscreen:", isOffscreenString); 304 | attribute.Tooltip = "Value that indicates whether the UI Automation element is visible on the screen"; 305 | this.listAttributes.Add(attribute); 306 | } 307 | catch { } 308 | } 309 | 310 | if (PropertySettings.hasIsPassword == true) 311 | { 312 | try 313 | { 314 | string isPasswordString = node.Element.CachedIsPassword.ToString(); 315 | Attribute attribute = new Attribute("IsPassword:", isPasswordString); 316 | attribute.Tooltip = "Value that indicates whether the UI Automation element contains protected content"; 317 | this.listAttributes.Add(attribute); 318 | } 319 | catch { } 320 | } 321 | 322 | if (PropertySettings.hasIsRequiredForForm == true) 323 | { 324 | try 325 | { 326 | string isRequiredForFormString = node.Element.CachedIsRequiredForForm.ToString(); 327 | Attribute attribute = new Attribute("IsRequiredForForm:", isRequiredForFormString); 328 | attribute.Tooltip = "Indicates whether the UI Automation element is required to be filled out on a form"; 329 | this.listAttributes.Add(attribute); 330 | } 331 | catch { } 332 | } 333 | 334 | if (PropertySettings.hasItemStatus == true) 335 | { 336 | try 337 | { 338 | string itemStatusString = "\"" + node.Element.CachedItemStatus + "\""; 339 | Attribute attribute = new Attribute("ItemStatus:", itemStatusString); 340 | attribute.Tooltip = "Description of the status of an item within an element"; 341 | this.listAttributes.Add(attribute); 342 | } 343 | catch { } 344 | } 345 | 346 | if (PropertySettings.hasItemType == true) 347 | { 348 | try 349 | { 350 | string itemTypeString = "\"" + node.Element.CachedItemType + "\""; 351 | Attribute attribute = new Attribute("ItemType:", itemTypeString); 352 | attribute.Tooltip = "Description of the type of an item"; 353 | this.listAttributes.Add(attribute); 354 | } 355 | catch { } 356 | } 357 | 358 | if (PropertySettings.hasLabeledBy == true) 359 | { 360 | try 361 | { 362 | IUIAutomationElement labeledBy = node.Element.CachedLabeledBy; 363 | if (labeledBy != null) 364 | { 365 | TreeNode nodeLabeledBy = new TreeNode(labeledBy); 366 | string labeledByString = nodeLabeledBy.ToString(); 367 | Attribute attribute = new Attribute("Labeled by:", labeledByString); 368 | attribute.Tooltip = "Element that contains the text label for this element"; 369 | attribute.UnderneathElement = labeledBy; 370 | this.listAttributes.Add(attribute); 371 | } 372 | } 373 | catch { } 374 | } 375 | 376 | //get control type 377 | if (PropertySettings.hasLocalizedControlType == true) 378 | { 379 | try 380 | { 381 | string localizedType = "\"" + node.Element.CachedLocalizedControlType + "\""; 382 | Attribute attribute = new Attribute("Localized control type:", localizedType); 383 | attribute.Tooltip = "Gets a description of the control type"; 384 | this.listAttributes.Add(attribute); 385 | } 386 | catch { } 387 | } 388 | 389 | //get name 390 | if (PropertySettings.hasName == true) 391 | { 392 | try 393 | { 394 | string name = node.Element.CachedName; 395 | 396 | if (name != null && name.Length > maxNameLength) 397 | { 398 | name = name.Substring(0, maxNameLength); 399 | name += "..."; 400 | } 401 | 402 | name = "\"" + name + "\""; 403 | Attribute attribute = new Attribute("Name:", name); 404 | attribute.Tooltip = "Name of the element"; 405 | this.listAttributes.Add(attribute); 406 | } 407 | catch { } 408 | } 409 | 410 | //get window handle 411 | if (PropertySettings.hasNativeWindowHandle == true) 412 | { 413 | try 414 | { 415 | string windowHandleString = node.Element.CachedNativeWindowHandle.ToString("X"); 416 | Attribute attribute = new Attribute("Native Window handle:", "0x" + windowHandleString); 417 | attribute.Tooltip = "Handle of the element's window"; 418 | this.listAttributes.Add(attribute); 419 | } 420 | catch { } 421 | } 422 | 423 | if (PropertySettings.hasOrientation == true) 424 | { 425 | try 426 | { 427 | string orientationString = node.Element.CachedOrientation.ToString(); 428 | Attribute attribute = new Attribute("Orientation:", orientationString); 429 | attribute.Tooltip = "Orientation of the control"; 430 | this.listAttributes.Add(attribute); 431 | } 432 | catch { } 433 | } 434 | 435 | //get process id 436 | if (PropertySettings.hasProcessId == true) 437 | { 438 | try 439 | { 440 | int pid = node.Element.CachedProcessId; 441 | Process process = null; 442 | try 443 | { 444 | process = Process.GetProcessById(pid); 445 | } 446 | catch { } 447 | 448 | string processString = ""; 449 | string attrName = ""; 450 | if (process != null) 451 | { 452 | processString = process.ProcessName + ".exe (PID: " + pid.ToString() + ")"; 453 | attrName = "Process:"; 454 | } 455 | else 456 | { 457 | processString = pid.ToString() + " - not running"; 458 | attrName = "ProcessId:"; 459 | } 460 | 461 | Attribute attribute = new Attribute(attrName, processString); 462 | attribute.Tooltip = "Process identifier (ID) of this element"; 463 | this.listAttributes.Add(attribute); 464 | } 465 | catch { } 466 | } 467 | 468 | if (PropertySettings.hasProviderDescription == true) 469 | { 470 | try 471 | { 472 | string providerDescription = node.Element.CachedProviderDescription; 473 | Attribute attribute = new Attribute("Provider Description:", providerDescription); 474 | attribute.Tooltip = "Description of the provider for this element"; 475 | this.listAttributes.Add(attribute); 476 | } 477 | catch { } 478 | } 479 | 480 | //get runtime id 481 | if (PropertySettings.hasRuntimeId == true) 482 | { 483 | try 484 | { 485 | Array runtimeId = node.Element.GetCachedPropertyValue(UIA_PropertyIds.UIA_RuntimeIdPropertyId) as Array; 486 | if (runtimeId != null) 487 | { 488 | string[] runtimeIdStrings = ArrayToStringArray(runtimeId); 489 | string runtimeIdString = "[" + string.Join(",", runtimeIdStrings) + "]"; 490 | Attribute attribute = new Attribute("RuntimeId:", runtimeIdString); 491 | attribute.Tooltip = "Unique identifier assigned to the user interface (UI) item"; 492 | this.listAttributes.Add(attribute); 493 | } 494 | } 495 | catch { } 496 | } 497 | 498 | //get supported patterns 499 | string supportedPatterns = ""; 500 | foreach (int propertyid in properties.Keys) 501 | { 502 | bool isSupported = false; 503 | try 504 | { 505 | isSupported = (bool)node.Element.GetCachedPropertyValue(propertyid); 506 | } 507 | catch { } 508 | 509 | if (isSupported == true) 510 | { 511 | if (supportedPatterns != "") 512 | { 513 | //supportedPatterns += ", "; 514 | supportedPatterns += Environment.NewLine; 515 | } 516 | 517 | supportedPatterns += properties[propertyid]; 518 | } 519 | } 520 | 521 | try 522 | { 523 | Attribute attr = new Attribute("Supported Patterns:", supportedPatterns); 524 | attr.Tooltip = "Control patterns that this Automation Element supported"; 525 | this.listAttributes.Add(attr); 526 | } 527 | catch { } 528 | 529 | Attribute emptyAttribute = new Attribute("", ""); 530 | this.listAttributes.Add(emptyAttribute); 531 | 532 | IUIAutomationElement2 element2 = node.Element as IUIAutomationElement2; 533 | if (element2 != null) 534 | { 535 | Attribute attribute = new Attribute("============", "IUIAutomationElement2 ========"); 536 | attribute.Tooltip = "Properties added in IUIAutomationElement2 interface"; 537 | this.listAttributes.Add(attribute); 538 | 539 | try 540 | { 541 | int optimizeForVisualContent = element2.CachedOptimizeForVisualContent; 542 | attribute = new Attribute("OptimizeForVisualContent:", optimizeForVisualContent.ToString()); 543 | attribute.Tooltip = "Indicates whether the provider exposes only elements that are visible"; 544 | this.listAttributes.Add(attribute); 545 | } 546 | catch {} 547 | 548 | try 549 | { 550 | LiveSetting liveSetting = element2.CachedLiveSetting; 551 | attribute = new Attribute("LiveSetting:", liveSetting.ToString()); 552 | attribute.Tooltip = "Indicates the type of notifications, if any, that the element sends when the content of the element changes"; 553 | this.listAttributes.Add(attribute); 554 | } 555 | catch {} 556 | } 557 | 558 | IUIAutomationElement3 element3 = node.Element as IUIAutomationElement3; 559 | if (element3 != null) 560 | { 561 | Attribute attribute = new Attribute("============", "IUIAutomationElement3 ========"); 562 | attribute.Tooltip = "Properties added in IUIAutomationElement3 interface"; 563 | this.listAttributes.Add(attribute); 564 | 565 | try 566 | { 567 | int isPeripheral = element3.CachedIsPeripheral; 568 | attribute = new Attribute("IsPeripheral:", isPeripheral.ToString()); 569 | attribute.Tooltip = "The current peripheral UI indicator for the element"; 570 | this.listAttributes.Add(attribute); 571 | } 572 | catch {} 573 | } 574 | 575 | IUIAutomationElement4 element4 = node.Element as IUIAutomationElement4; 576 | if (element4 != null) 577 | { 578 | Attribute attribute = new Attribute("============", "IUIAutomationElement4 ========"); 579 | attribute.Tooltip = "Properties added in IUIAutomationElement4 interface"; 580 | this.listAttributes.Add(attribute); 581 | 582 | try 583 | { 584 | int positionInSet = element4.CachedPositionInSet; 585 | attribute = new Attribute("PositionInSet:", positionInSet.ToString()); 586 | attribute.Tooltip = "The current 1-based integer for the ordinal position in the set for the element"; 587 | this.listAttributes.Add(attribute); 588 | } 589 | catch {} 590 | 591 | try 592 | { 593 | int sizeOfSet = element4.CachedSizeOfSet; 594 | attribute = new Attribute("SizeOfSet:", sizeOfSet.ToString()); 595 | attribute.Tooltip = "The current 1-based integer for the size of the set where the element is located"; 596 | this.listAttributes.Add(attribute); 597 | } 598 | catch {} 599 | 600 | try 601 | { 602 | int level = element4.CachedLevel; 603 | attribute = new Attribute("Level:", level.ToString()); 604 | attribute.Tooltip = "The current 1-based integer for the level (hierarchy) for the element"; 605 | this.listAttributes.Add(attribute); 606 | } 607 | catch {} 608 | 609 | try 610 | { 611 | int[] annotationTypes = element4.CachedAnnotationTypes; 612 | attribute = new Attribute("AnnotationTypes:", "[" + IntArrayToString(annotationTypes) + "]"); 613 | attribute.Tooltip = "The current list of annotation types associated with this element, such as comment, header, footer, and so on"; 614 | this.listAttributes.Add(attribute); 615 | } 616 | catch {} 617 | } 618 | 619 | IUIAutomationElement5 element5 = node.Element as IUIAutomationElement5; 620 | if (element5 != null) 621 | { 622 | Attribute attribute = new Attribute("============", "IUIAutomationElement5 ========"); 623 | attribute.Tooltip = "Properties added in IUIAutomationElement5 interface"; 624 | this.listAttributes.Add(attribute); 625 | 626 | try 627 | { 628 | int landmarkType = element5.CachedLandmarkType; 629 | string landmarkTypeString = null; 630 | if (LandmarkTypesDict.ContainsKey(landmarkType)) 631 | { 632 | landmarkTypeString = LandmarkTypesDict[landmarkType]; 633 | } 634 | else 635 | { 636 | landmarkTypeString = landmarkType.ToString(); 637 | } 638 | attribute = new Attribute("LandmarkType:", landmarkTypeString); 639 | attribute.Tooltip = "The current landmark type ID for the automation element"; 640 | this.listAttributes.Add(attribute); 641 | } 642 | catch {} 643 | 644 | try 645 | { 646 | string localizedLandmarkType = element5.CachedLocalizedLandmarkType; 647 | attribute = new Attribute("LocalizedLandmarkType:", "\"" + localizedLandmarkType + "\""); 648 | attribute.Tooltip = "A string containing the current localized landmark type for the automation element"; 649 | this.listAttributes.Add(attribute); 650 | } 651 | catch {} 652 | } 653 | 654 | IUIAutomationElement6 element6 = node.Element as IUIAutomationElement6; 655 | if (element6 != null) 656 | { 657 | Attribute attribute = new Attribute("============", "IUIAutomationElement6 ========"); 658 | attribute.Tooltip = "Properties added in IUIAutomationElement6 interface"; 659 | this.listAttributes.Add(attribute); 660 | 661 | try 662 | { 663 | string fullDescription = element6.CachedFullDescription; 664 | attribute = new Attribute("FullDescription:", "\"" + fullDescription + "\""); 665 | attribute.Tooltip = "The current full description of the automation element"; 666 | this.listAttributes.Add(attribute); 667 | } 668 | catch {} 669 | } 670 | 671 | IUIAutomationElement8 element8 = node.Element as IUIAutomationElement8; 672 | if (element8 != null) 673 | { 674 | Attribute attribute = new Attribute("============", "IUIAutomationElement8 ========"); 675 | attribute.Tooltip = "Properties added in IUIAutomationElement8 interface"; 676 | this.listAttributes.Add(attribute); 677 | 678 | try 679 | { 680 | int headingLevel = element8.CachedHeadingLevel; 681 | attribute = new Attribute("HeadingLevel:", HeadingLevelsDict[headingLevel]); 682 | attribute.Tooltip = "The current heading level of the automation element"; 683 | this.listAttributes.Add(attribute); 684 | } 685 | catch {} 686 | } 687 | 688 | IUIAutomationElement9 element9 = node.Element as IUIAutomationElement9; 689 | if (element9 != null) 690 | { 691 | Attribute attribute = new Attribute("============", "IUIAutomationElement9 ========"); 692 | attribute.Tooltip = "Properties added in IUIAutomationElement9 interface"; 693 | this.listAttributes.Add(attribute); 694 | 695 | try 696 | { 697 | int isDialog = element9.CachedIsDialog; 698 | attribute = new Attribute("IsDialog:", isDialog.ToString()); 699 | attribute.Tooltip = "The current is dialog window indicator for the element"; 700 | this.listAttributes.Add(attribute); 701 | } 702 | catch {} 703 | } 704 | } 705 | } 706 | } -------------------------------------------------------------------------------- /src/AutomationSpy/AutomationSpy.Current.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using System.Diagnostics; 4 | using System.Text; 5 | using Interop.UIAutomationClient; 6 | using System.Collections.Generic; 7 | 8 | namespace dDeltaSolutions.Spy 9 | { 10 | public partial class MainWindow 11 | { 12 | private void GetCurrentInformation(TreeNode node) 13 | { 14 | if (PropertySettings.hasAcceleratorKey == true) 15 | { 16 | try 17 | { 18 | string acceleratorKey = "\"" + node.Element.CurrentAcceleratorKey + "\""; 19 | Attribute attribute = new Attribute("Accelerator Key:", acceleratorKey); 20 | attribute.Tooltip = "String containing the accelerator key combinations for the element"; 21 | this.listAttributes.Add(attribute); 22 | } 23 | catch { } 24 | } 25 | 26 | if (PropertySettings.hasAccessKey == true) 27 | { 28 | try 29 | { 30 | string accessKey = "\"" + node.Element.CurrentAccessKey + "\""; 31 | Attribute attribute = new Attribute("Access Key:", accessKey); 32 | attribute.Tooltip = "String containing the access key character for the element"; 33 | this.listAttributes.Add(attribute); 34 | } 35 | catch { } 36 | } 37 | 38 | if (PropertySettings.hasAriaProperties == true) 39 | { 40 | try 41 | { 42 | string ariaProperties = "\"" + node.Element.CurrentAriaProperties + "\""; 43 | Attribute attribute = new Attribute("Aria Properties:", ariaProperties); 44 | attribute.Tooltip = "Accessible Rich Internet Applications (ARIA) properties of the element"; 45 | this.listAttributes.Add(attribute); 46 | } 47 | catch { } 48 | } 49 | 50 | if (PropertySettings.hasAriaRole == true) 51 | { 52 | try 53 | { 54 | string ariaRole = "\"" + node.Element.CurrentAriaRole + "\""; 55 | Attribute attribute = new Attribute("Aria Role:", ariaRole); 56 | attribute.Tooltip = "Accessible Rich Internet Applications (ARIA) role of the element"; 57 | this.listAttributes.Add(attribute); 58 | } 59 | catch { } 60 | } 61 | 62 | //get automation id 63 | if (PropertySettings.hasAutomationId == true) 64 | { 65 | try 66 | { 67 | string automationIdString = "\"" + node.Element.CurrentAutomationId + "\""; 68 | Attribute attribute = new Attribute("AutomationId:", automationIdString); 69 | attribute.Tooltip = "String containing the UI Automation identifier (ID) for the element"; 70 | this.listAttributes.Add(attribute); 71 | } 72 | catch { } 73 | } 74 | 75 | //get bounding rectangle 76 | if (PropertySettings.hasBoundingRectangle == true) 77 | { 78 | try 79 | { 80 | tagRECT boundingRectangle = node.Element.CurrentBoundingRectangle; 81 | string rectangleString = RectangleToString(boundingRectangle); 82 | Attribute attribute = new Attribute("Bounding rectangle:", rectangleString); 83 | attribute.Tooltip = "Coordinates of the rectangle that completely encloses the element"; 84 | this.listAttributes.Add(attribute); 85 | } 86 | catch { } 87 | } 88 | 89 | //get window class 90 | if (PropertySettings.hasClassName == true) 91 | { 92 | try 93 | { 94 | string windowClass = "\"" + node.Element.CurrentClassName + "\""; 95 | Attribute attribute = new Attribute("Class Name:", windowClass); 96 | attribute.Tooltip = "String containing the class name of the element as assigned by the control developer"; 97 | this.listAttributes.Add(attribute); 98 | } 99 | catch { } 100 | } 101 | 102 | //clickable point 103 | if (PropertySettings.hasClickablePoint == true) 104 | { 105 | try 106 | { 107 | //bool skip = false; 108 | if (IsWindows7() && (MainWindow.CompareElements(node.Element, uiAutomation.GetRootElement()) == true)) 109 | { 110 | // On Windows 7 don't get ClickablePoint for Desktop 111 | } 112 | else 113 | { 114 | tagPOINT clickablePoint; //= new tagRECT(); 115 | if (node.Element.GetClickablePoint(out clickablePoint) != 0) 116 | { 117 | string pointString = GetStringFromPoint(clickablePoint); 118 | Attribute attribute = new Attribute("ClickablePoint:", pointString); 119 | attribute.Tooltip = "Point on the Automation Element that can be clicked"; 120 | this.listAttributes.Add(attribute); 121 | } 122 | } 123 | } 124 | catch { } 125 | } 126 | 127 | if (PropertySettings.hasControllerFor == true) 128 | { 129 | try 130 | { 131 | IUIAutomationElementArray array = node.Element.CurrentControllerFor; 132 | for (int i = 0; i < array.Length; i++) 133 | { 134 | IUIAutomationElement element = array.GetElement(i); 135 | TreeNode elementNode = new TreeNode(element); 136 | string controllerForString = elementNode.ToString(); 137 | Attribute attribute = new Attribute("ControllerFor[" + i + "]:", controllerForString); 138 | attribute.Tooltip = "Array of elements for which this element serves as the controller"; 139 | attribute.UnderneathElement = element; 140 | this.listAttributes.Add(attribute); 141 | } 142 | } 143 | catch {} 144 | } 145 | 146 | //get Control Type 147 | if (PropertySettings.hasControlType == true) 148 | { 149 | try 150 | { 151 | int controlTypeId = node.Element.CurrentControlType; 152 | string controlTypeString = Helper.ControlTypeIdToString(controlTypeId) + " (" + controlTypeId + ")"; 153 | Attribute attribute = new Attribute("Control type:", controlTypeString); 154 | attribute.Tooltip = "Control type of the element"; 155 | this.listAttributes.Add(attribute); 156 | } 157 | catch { } 158 | } 159 | 160 | if (PropertySettings.hasCulture == true) 161 | { 162 | try 163 | { 164 | int culture = node.Element.CurrentCulture; 165 | Attribute attribute = new Attribute("Culture:", culture.ToString()); 166 | attribute.Tooltip = "Culture identifier"; 167 | this.listAttributes.Add(attribute); 168 | } 169 | catch { } 170 | } 171 | 172 | if (PropertySettings.hasDescribedBy == true) 173 | { 174 | try 175 | { 176 | IUIAutomationElementArray array = node.Element.CurrentDescribedBy; 177 | for (int i = 0; i < array.Length; i++) 178 | { 179 | IUIAutomationElement element = array.GetElement(i); 180 | TreeNode elementNode = new TreeNode(element); 181 | string describedByString = elementNode.ToString(); 182 | Attribute attribute = new Attribute("DescribedBy[" + i + "]:", describedByString); 183 | attribute.Tooltip = "Array of elements that describe this element"; 184 | attribute.UnderneathElement = element; 185 | this.listAttributes.Add(attribute); 186 | } 187 | } 188 | catch {} 189 | } 190 | 191 | if (PropertySettings.hasFlowsTo == true) 192 | { 193 | try 194 | { 195 | IUIAutomationElementArray array = node.Element.CurrentFlowsTo; 196 | for (int i = 0; i < array.Length; i++) 197 | { 198 | IUIAutomationElement element = array.GetElement(i); 199 | TreeNode elementNode = new TreeNode(element); 200 | string flowsToString = elementNode.ToString(); 201 | Attribute attribute = new Attribute("FlowsTo[" + i + "]:", flowsToString); 202 | attribute.Tooltip = "Array of elements that indicates the reading order after the current element"; 203 | attribute.UnderneathElement = element; 204 | this.listAttributes.Add(attribute); 205 | } 206 | } 207 | catch {} 208 | } 209 | 210 | if (PropertySettings.hasFrameworkId == true) 211 | { 212 | try 213 | { 214 | string frameworkIdString = node.Element.CurrentFrameworkId; 215 | Attribute attribute = new Attribute("FrameworkId:", "\"" + frameworkIdString + "\""); 216 | attribute.Tooltip = "Name of the underlying UI framework"; 217 | this.listAttributes.Add(attribute); 218 | } 219 | catch { } 220 | } 221 | 222 | if (PropertySettings.hasHasKeyboardFocus == true) 223 | { 224 | try 225 | { 226 | int hasKeyboboardFocus = node.Element.CurrentHasKeyboardFocus; 227 | Attribute attribute = new Attribute("HasKeyboardFocus:", hasKeyboboardFocus.ToString()); 228 | attribute.Tooltip = "Value that indicates whether the element has keyboard focus"; 229 | this.listAttributes.Add(attribute); 230 | } 231 | catch { } 232 | } 233 | 234 | if (PropertySettings.hasHelpText == true) 235 | { 236 | try 237 | { 238 | string helpText = "\"" + node.Element.CurrentHelpText + "\""; 239 | Attribute attribute = new Attribute("Help Text:", helpText); 240 | attribute.Tooltip = "Help text associated with the element"; 241 | this.listAttributes.Add(attribute); 242 | } 243 | catch { } 244 | } 245 | 246 | if (PropertySettings.hasIsContentElement == true) 247 | { 248 | try 249 | { 250 | string isContentString = node.Element.CurrentIsContentElement.ToString(); 251 | Attribute attribute = new Attribute("IsContentElement:", isContentString); 252 | attribute.Tooltip = "Value that specifies whether the element is a content element"; 253 | this.listAttributes.Add(attribute); 254 | } 255 | catch { } 256 | } 257 | 258 | if (PropertySettings.hasIsControlElement == true) 259 | { 260 | try 261 | { 262 | string isControlString = node.Element.CurrentIsControlElement.ToString(); 263 | Attribute attribute = new Attribute("IsControlElement:", isControlString); 264 | attribute.Tooltip = "Value that indicates whether the element is viewed as a control"; 265 | this.listAttributes.Add(attribute); 266 | } 267 | catch { } 268 | } 269 | 270 | if (PropertySettings.hasIsDataValidForForm == true) 271 | { 272 | try 273 | { 274 | string isDataValidForFormString = node.Element.CurrentIsDataValidForForm.ToString(); 275 | Attribute attribute = new Attribute("IsDataValidForForm:", isDataValidForFormString); 276 | attribute.Tooltip = "Indicates whether the element contains valid data for a form"; 277 | this.listAttributes.Add(attribute); 278 | } 279 | catch { } 280 | } 281 | 282 | if (PropertySettings.hasIsEnabled == true) 283 | { 284 | try 285 | { 286 | string isEnabledString = node.Element.CurrentIsEnabled.ToString(); 287 | Attribute attribute = new Attribute("IsEnabled:", isEnabledString); 288 | attribute.Tooltip = "Value that indicates whether the element is enabled"; 289 | this.listAttributes.Add(attribute); 290 | } 291 | catch { } 292 | } 293 | 294 | if (PropertySettings.hasIsKeyboardFocusable == true) 295 | { 296 | try 297 | { 298 | string isKeyboardFocusableString = node.Element.CurrentIsKeyboardFocusable.ToString(); 299 | Attribute attribute = new Attribute("IsKeyboardFocusable:", isKeyboardFocusableString); 300 | attribute.Tooltip = "Value that indicates whether the UI Automation element can accept keyboard focus"; 301 | this.listAttributes.Add(attribute); 302 | } 303 | catch { } 304 | } 305 | 306 | if (PropertySettings.hasIsOffscreen == true) 307 | { 308 | try 309 | { 310 | string isOffscreenString = node.Element.CurrentIsOffscreen.ToString(); 311 | Attribute attribute = new Attribute("IsOffscreen:", isOffscreenString); 312 | attribute.Tooltip = "Value that indicates whether the UI Automation element is visible on the screen"; 313 | this.listAttributes.Add(attribute); 314 | } 315 | catch { } 316 | } 317 | 318 | if (PropertySettings.hasIsPassword == true) 319 | { 320 | try 321 | { 322 | string isPasswordString = node.Element.CurrentIsPassword.ToString(); 323 | Attribute attribute = new Attribute("IsPassword:", isPasswordString); 324 | attribute.Tooltip = "Value that indicates whether the UI Automation element contains protected content"; 325 | this.listAttributes.Add(attribute); 326 | } 327 | catch { } 328 | } 329 | 330 | if (PropertySettings.hasIsRequiredForForm == true) 331 | { 332 | try 333 | { 334 | string isRequiredForFormString = node.Element.CurrentIsRequiredForForm.ToString(); 335 | Attribute attribute = new Attribute("IsRequiredForForm:", isRequiredForFormString); 336 | attribute.Tooltip = "Indicates whether the UI Automation element is required to be filled out on a form"; 337 | this.listAttributes.Add(attribute); 338 | } 339 | catch { } 340 | } 341 | 342 | if (PropertySettings.hasItemStatus == true) 343 | { 344 | try 345 | { 346 | string itemStatusString = "\"" + node.Element.CurrentItemStatus + "\""; 347 | Attribute attribute = new Attribute("ItemStatus:", itemStatusString); 348 | attribute.Tooltip = "Description of the status of an item within an element"; 349 | this.listAttributes.Add(attribute); 350 | } 351 | catch { } 352 | } 353 | 354 | if (PropertySettings.hasItemType == true) 355 | { 356 | try 357 | { 358 | string itemTypeString = "\"" + node.Element.CurrentItemType + "\""; 359 | Attribute attribute = new Attribute("ItemType:", itemTypeString); 360 | attribute.Tooltip = "Description of the type of an item"; 361 | this.listAttributes.Add(attribute); 362 | } 363 | catch { } 364 | } 365 | 366 | if (PropertySettings.hasLabeledBy == true) 367 | { 368 | try 369 | { 370 | IUIAutomationElement labeledBy = node.Element.CurrentLabeledBy; 371 | 372 | if (labeledBy != null) 373 | { 374 | TreeNode nodeLabeledBy = new TreeNode(labeledBy); 375 | string labeledByString = nodeLabeledBy.ToString(); 376 | Attribute attribute = new Attribute("Labeled by:", labeledByString); 377 | attribute.Tooltip = "Element that contains the text label for this element"; 378 | attribute.UnderneathElement = labeledBy; 379 | this.listAttributes.Add(attribute); 380 | } 381 | } 382 | catch { } 383 | } 384 | 385 | //get control type 386 | if (PropertySettings.hasLocalizedControlType == true) 387 | { 388 | try 389 | { 390 | string localizedType = "\"" + node.Element.CurrentLocalizedControlType + "\""; 391 | Attribute attribute = new Attribute("Localized control type:", localizedType); 392 | attribute.Tooltip = "Gets a description of the control type"; 393 | this.listAttributes.Add(attribute); 394 | } 395 | catch { } 396 | } 397 | 398 | //get name 399 | if (PropertySettings.hasName == true) 400 | { 401 | try 402 | { 403 | string name = node.Element.CurrentName; 404 | 405 | if (name != null && name.Length > maxNameLength) 406 | { 407 | name = name.Substring(0, maxNameLength); 408 | name += "..."; 409 | } 410 | 411 | name = "\"" + name + "\""; 412 | Attribute attribute = new Attribute("Name:", name); 413 | attribute.Tooltip = "Name of the element"; 414 | this.listAttributes.Add(attribute); 415 | } 416 | catch { } 417 | } 418 | 419 | //get window handle 420 | if (PropertySettings.hasNativeWindowHandle == true) 421 | { 422 | try 423 | { 424 | string windowHandleString = ""; 425 | 426 | IntPtr hwnd = node.Element.CurrentNativeWindowHandle; 427 | if (hwnd != IntPtr.Zero) 428 | { 429 | StringBuilder sbName = new StringBuilder(256); 430 | GetWindowText(hwnd, sbName, 256); 431 | 432 | StringBuilder sbClassName = new StringBuilder(256); 433 | GetClassName(hwnd, sbClassName, 256); 434 | 435 | windowHandleString = "0x" + hwnd.ToString("X") + 436 | ", WindowText: \"" + sbName.ToString() + "\", WindowClass: \"" + sbClassName.ToString() + "\""; 437 | } 438 | else 439 | { 440 | windowHandleString = "0x0"; 441 | } 442 | 443 | Attribute attribute = new Attribute("Native Window handle:", windowHandleString); 444 | attribute.Tooltip = "Handle of the element's window"; 445 | this.listAttributes.Add(attribute); 446 | } 447 | catch { } 448 | } 449 | 450 | if (PropertySettings.hasOrientation == true) 451 | { 452 | try 453 | { 454 | string orientationString = node.Element.CurrentOrientation.ToString(); 455 | Attribute attribute = new Attribute("Orientation:", orientationString); 456 | attribute.Tooltip = "Orientation of the control"; 457 | this.listAttributes.Add(attribute); 458 | } 459 | catch { } 460 | } 461 | 462 | //get process id 463 | if (PropertySettings.hasProcessId == true) 464 | { 465 | try 466 | { 467 | int pid = node.Element.CurrentProcessId; 468 | Process process = Process.GetProcessById(pid); 469 | string processString = process.ProcessName + ".exe (PID: " + pid.ToString() + ")"; 470 | Attribute attribute = new Attribute("Process:", processString); 471 | attribute.Tooltip = "Process identifier (ID) of this element"; 472 | this.listAttributes.Add(attribute); 473 | } 474 | catch { } 475 | } 476 | 477 | if (PropertySettings.hasProviderDescription == true) 478 | { 479 | try 480 | { 481 | string providerDescription = node.Element.CurrentProviderDescription; 482 | Attribute attribute = new Attribute("Provider Description:", providerDescription); 483 | attribute.Tooltip = "Description of the provider for this element"; 484 | this.listAttributes.Add(attribute); 485 | } 486 | catch { } 487 | } 488 | 489 | //get runtime id 490 | if (PropertySettings.hasRuntimeId == true) 491 | { 492 | try 493 | { 494 | int[] runtimeId = node.Element.GetRuntimeId(); 495 | //string[] runtimeIdStrings = ArrayToStringArray(runtimeId); 496 | 497 | //string runtimeIdString = "[" + string.Join(",", runtimeIdStrings) + "]"; 498 | string runtimeIdString = "[" + IntArrayToString(runtimeId) + "]"; 499 | Attribute attribute = new Attribute("RuntimeId:", runtimeIdString); 500 | attribute.Tooltip = "Unique identifier assigned to the user interface (UI) item"; 501 | this.listAttributes.Add(attribute); 502 | } 503 | catch { } 504 | } 505 | 506 | #region supported patterns 507 | try 508 | { 509 | FillPatternsDictionary(); 510 | 511 | string supportedPatterns = string.Empty; 512 | foreach (int patternId in patternsIds.Keys) 513 | { 514 | try 515 | { 516 | if (node.Element.GetCurrentPattern(patternId) != null) 517 | { 518 | patternsIds[patternId].IsSupported = true; 519 | 520 | if (supportedPatterns != string.Empty) 521 | { 522 | supportedPatterns += Environment.NewLine; 523 | } 524 | 525 | supportedPatterns += patternsIds[patternId]; 526 | } 527 | } 528 | catch {} 529 | } 530 | 531 | Attribute attribute = new Attribute("Supported Patterns:", supportedPatterns); 532 | attribute.Tooltip = "Control patterns that this Automation Element supports"; 533 | this.listAttributes.Add(attribute); 534 | } 535 | catch {} 536 | #endregion 537 | 538 | Attribute emptyAttribute = new Attribute("", ""); 539 | this.listAttributes.Add(emptyAttribute); 540 | 541 | IUIAutomationElement2 element2 = node.Element as IUIAutomationElement2; 542 | if (element2 != null) 543 | { 544 | Attribute attribute = new Attribute("============", "IUIAutomationElement2 ========"); 545 | attribute.Tooltip = "Properties added in IUIAutomationElement2 interface"; 546 | this.listAttributes.Add(attribute); 547 | 548 | try 549 | { 550 | int optimizeForVisualContent = element2.CurrentOptimizeForVisualContent; 551 | attribute = new Attribute("OptimizeForVisualContent:", optimizeForVisualContent.ToString()); 552 | attribute.Tooltip = "Indicates whether the provider exposes only elements that are visible"; 553 | this.listAttributes.Add(attribute); 554 | } 555 | catch {} 556 | 557 | try 558 | { 559 | LiveSetting liveSetting = element2.CurrentLiveSetting; 560 | attribute = new Attribute("LiveSetting:", liveSetting.ToString()); 561 | attribute.Tooltip = "Indicates the type of notifications, if any, that the element sends when the content of the element changes"; 562 | this.listAttributes.Add(attribute); 563 | } 564 | catch {} 565 | } 566 | 567 | IUIAutomationElement3 element3 = node.Element as IUIAutomationElement3; 568 | if (element3 != null) 569 | { 570 | Attribute attribute = new Attribute("============", "IUIAutomationElement3 ========"); 571 | attribute.Tooltip = "Properties added in IUIAutomationElement3 interface"; 572 | this.listAttributes.Add(attribute); 573 | 574 | try 575 | { 576 | int isPeripheral = element3.CurrentIsPeripheral; 577 | attribute = new Attribute("IsPeripheral:", isPeripheral.ToString()); 578 | attribute.Tooltip = "The current peripheral UI indicator for the element"; 579 | this.listAttributes.Add(attribute); 580 | } 581 | catch {} 582 | } 583 | 584 | IUIAutomationElement4 element4 = node.Element as IUIAutomationElement4; 585 | if (element4 != null) 586 | { 587 | Attribute attribute = new Attribute("============", "IUIAutomationElement4 ========"); 588 | attribute.Tooltip = "Properties added in IUIAutomationElement4 interface"; 589 | this.listAttributes.Add(attribute); 590 | 591 | try 592 | { 593 | int positionInSet = element4.CurrentPositionInSet; 594 | attribute = new Attribute("PositionInSet:", positionInSet.ToString()); 595 | attribute.Tooltip = "The current 1-based integer for the ordinal position in the set for the element"; 596 | this.listAttributes.Add(attribute); 597 | } 598 | catch {} 599 | 600 | try 601 | { 602 | int sizeOfSet = element4.CurrentSizeOfSet; 603 | attribute = new Attribute("SizeOfSet:", sizeOfSet.ToString()); 604 | attribute.Tooltip = "The current 1-based integer for the size of the set where the element is located"; 605 | this.listAttributes.Add(attribute); 606 | } 607 | catch {} 608 | 609 | try 610 | { 611 | int level = element4.CurrentLevel; 612 | attribute = new Attribute("Level:", level.ToString()); 613 | attribute.Tooltip = "The current 1-based integer for the level (hierarchy) for the element"; 614 | this.listAttributes.Add(attribute); 615 | } 616 | catch {} 617 | 618 | try 619 | { 620 | int[] annotationTypes = element4.CurrentAnnotationTypes; 621 | //MessageBox.Show("Length: " + annotationTypes.Length); 622 | attribute = new Attribute("AnnotationTypes:", "[" + IntArrayToString(annotationTypes) + "]"); 623 | attribute.Tooltip = "The current list of annotation types associated with this element, such as comment, header, footer, and so on"; 624 | this.listAttributes.Add(attribute); 625 | } 626 | catch {} 627 | } 628 | 629 | IUIAutomationElement5 element5 = node.Element as IUIAutomationElement5; 630 | if (element5 != null) 631 | { 632 | Attribute attribute = new Attribute("============", "IUIAutomationElement5 ========"); 633 | attribute.Tooltip = "Properties added in IUIAutomationElement5 interface"; 634 | this.listAttributes.Add(attribute); 635 | 636 | try 637 | { 638 | int landmarkType = element5.CurrentLandmarkType; 639 | string landmarkTypeString = null; 640 | if (LandmarkTypesDict.ContainsKey(landmarkType)) 641 | { 642 | landmarkTypeString = LandmarkTypesDict[landmarkType]; 643 | } 644 | else 645 | { 646 | landmarkTypeString = landmarkType.ToString(); 647 | } 648 | attribute = new Attribute("LandmarkType:", landmarkTypeString); 649 | attribute.Tooltip = "The current landmark type ID for the automation element"; 650 | this.listAttributes.Add(attribute); 651 | } 652 | catch {} 653 | 654 | try 655 | { 656 | string localizedLandmarkType = element5.CurrentLocalizedLandmarkType; 657 | attribute = new Attribute("LocalizedLandmarkType:", "\"" + localizedLandmarkType + "\""); 658 | attribute.Tooltip = "A string containing the current localized landmark type for the automation element"; 659 | this.listAttributes.Add(attribute); 660 | } 661 | catch {} 662 | } 663 | 664 | IUIAutomationElement6 element6 = node.Element as IUIAutomationElement6; 665 | if (element6 != null) 666 | { 667 | Attribute attribute = new Attribute("============", "IUIAutomationElement6 ========"); 668 | attribute.Tooltip = "Properties added in IUIAutomationElement6 interface"; 669 | this.listAttributes.Add(attribute); 670 | 671 | try 672 | { 673 | string fullDescription = element6.CurrentFullDescription; 674 | attribute = new Attribute("FullDescription:", "\"" + fullDescription + "\""); 675 | attribute.Tooltip = "The current full description of the automation element"; 676 | this.listAttributes.Add(attribute); 677 | } 678 | catch {} 679 | } 680 | 681 | IUIAutomationElement8 element8 = node.Element as IUIAutomationElement8; 682 | if (element8 != null) 683 | { 684 | Attribute attribute = new Attribute("============", "IUIAutomationElement8 ========"); 685 | attribute.Tooltip = "Properties added in IUIAutomationElement8 interface"; 686 | this.listAttributes.Add(attribute); 687 | 688 | try 689 | { 690 | int headingLevel = element8.CurrentHeadingLevel; 691 | attribute = new Attribute("HeadingLevel:", HeadingLevelsDict[headingLevel]); 692 | attribute.Tooltip = "The current heading level of the automation element"; 693 | this.listAttributes.Add(attribute); 694 | } 695 | catch {} 696 | } 697 | 698 | IUIAutomationElement9 element9 = node.Element as IUIAutomationElement9; 699 | if (element9 != null) 700 | { 701 | Attribute attribute = new Attribute("============", "IUIAutomationElement9 ========"); 702 | attribute.Tooltip = "Properties added in IUIAutomationElement9 interface"; 703 | this.listAttributes.Add(attribute); 704 | 705 | try 706 | { 707 | int isDialog = element9.CurrentIsDialog; 708 | attribute = new Attribute("IsDialog:", isDialog.ToString()); 709 | attribute.Tooltip = "The current is dialog window indicator for the element"; 710 | this.listAttributes.Add(attribute); 711 | } 712 | catch {} 713 | } 714 | } 715 | 716 | private static Dictionary HeadingLevelsDict = new Dictionary() 717 | { 718 | { UIA_HeadingLevelIds.HeadingLevel_None, "HeadingLevel_None" }, 719 | { UIA_HeadingLevelIds.HeadingLevel1, "HeadingLevel1" }, 720 | { UIA_HeadingLevelIds.HeadingLevel2, "HeadingLevel2" }, 721 | { UIA_HeadingLevelIds.HeadingLevel3, "HeadingLevel3" }, 722 | { UIA_HeadingLevelIds.HeadingLevel4, "HeadingLevel4" }, 723 | { UIA_HeadingLevelIds.HeadingLevel5, "HeadingLevel5" }, 724 | { UIA_HeadingLevelIds.HeadingLevel6, "HeadingLevel6" }, 725 | { UIA_HeadingLevelIds.HeadingLevel7, "HeadingLevel7" }, 726 | { UIA_HeadingLevelIds.HeadingLevel8, "HeadingLevel8" }, 727 | { UIA_HeadingLevelIds.HeadingLevel9, "HeadingLevel9" } 728 | }; 729 | 730 | private static Dictionary LandmarkTypesDict = new Dictionary() 731 | { 732 | { UIA_LandmarkTypeIds.UIA_CustomLandmarkTypeId, "UIA_CustomLandmarkTypeId" }, 733 | { UIA_LandmarkTypeIds.UIA_FormLandmarkTypeId, "UIA_FormLandmarkTypeId" }, 734 | { UIA_LandmarkTypeIds.UIA_MainLandmarkTypeId, "UIA_MainLandmarkTypeId" }, 735 | { UIA_LandmarkTypeIds.UIA_NavigationLandmarkTypeId, "UIA_NavigationLandmarkTypeId" }, 736 | { UIA_LandmarkTypeIds.UIA_SearchLandmarkTypeId, "UIA_SearchLandmarkTypeId" } 737 | }; 738 | } 739 | } -------------------------------------------------------------------------------- /src/AutomationSpy/AutomationSpy.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3549AB3D-03CD-4CAB-8CFD-949029F4101B} 8 | WinExe 9 | Properties 10 | AutomationSpy 11 | AutomationSpy 12 | v4.0 13 | 512 14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 4 16 | false 17 | 18 | 19 | C:\Projects\Kits\ 20 | true 21 | Disk 22 | true 23 | Foreground 24 | 7 25 | Days 26 | false 27 | false 28 | true 29 | 0 30 | 1.0.0.%2a 31 | false 32 | true 33 | true 34 | 35 | 36 | x86 37 | true 38 | full 39 | false 40 | bin\Debug\ 41 | DEBUG;TRACE 42 | prompt 43 | 4 44 | false 45 | 46 | 47 | x86 48 | pdbonly 49 | true 50 | bin\Release\ 51 | TRACE 52 | prompt 53 | 4 54 | false 55 | 56 | 57 | false 58 | 59 | 60 | 61 | 62 | 63 | 64 | 36004A7D890F315E67641C0EC8196D40A2EA643E 65 | 66 | 67 | AutomationSpy_TemporaryKey.pfx 68 | 69 | 70 | true 71 | 72 | 73 | false 74 | 75 | 76 | appicon.ico 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | True 94 | Lib\Interop.UIAutomationClient.dll 95 | 96 | 97 | 98 | 99 | MSBuild:Compile 100 | Designer 101 | 102 | 103 | WindowEventsOptions.xaml 104 | 105 | 106 | WindowActions.xaml 107 | 108 | 109 | MSBuild:Compile 110 | Designer 111 | 112 | 113 | Form 114 | 115 | 116 | AboutForm.cs 117 | 118 | 119 | App.xaml 120 | Code 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | MainWindow.xaml 129 | Code 130 | 131 | 132 | 133 | 134 | Designer 135 | MSBuild:Compile 136 | 137 | 138 | Designer 139 | MSBuild:Compile 140 | 141 | 142 | 143 | PropertySettings.xaml 144 | 145 | 146 | Designer 147 | MSBuild:Compile 148 | 149 | 150 | 151 | MoreAttributes.xaml 152 | 153 | 154 | Designer 155 | MSBuild:Compile 156 | 157 | 158 | 159 | WindowAllText.xaml 160 | 161 | 162 | Designer 163 | MSBuild:Compile 164 | 165 | 166 | 167 | 168 | Code 169 | 170 | 171 | True 172 | True 173 | Resources.resx 174 | 175 | 176 | True 177 | Settings.settings 178 | True 179 | 180 | 181 | AboutForm.cs 182 | 183 | 184 | ResXFileCodeGenerator 185 | Resources.Designer.cs 186 | 187 | 188 | SettingsSingleFileGenerator 189 | Settings.Designer.cs 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 221 | -------------------------------------------------------------------------------- /src/AutomationSpy/AutomationSpy.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | C:\Projects\Kits\|publish\ 5 | 6 | 7 | 8 | 9 | 10 | en-US 11 | false 12 | 13 | 14 | false 15 | 16 | -------------------------------------------------------------------------------- /src/AutomationSpy/Defines.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace dDeltaSolutions.Spy 3 | { 4 | internal abstract class UIA_ControlTypeIds 5 | { 6 | public const int UIA_ButtonControlTypeId = 50000; 7 | public const int UIA_CalendarControlTypeId = 50001; 8 | public const int UIA_CheckBoxControlTypeId = 50002; 9 | public const int UIA_ComboBoxControlTypeId = 50003; 10 | public const int UIA_EditControlTypeId = 50004; 11 | public const int UIA_HyperlinkControlTypeId = 50005; 12 | public const int UIA_ImageControlTypeId = 50006; 13 | public const int UIA_ListItemControlTypeId = 50007; 14 | public const int UIA_ListControlTypeId = 50008; 15 | public const int UIA_MenuControlTypeId = 50009; 16 | public const int UIA_MenuBarControlTypeId = 50010; 17 | public const int UIA_MenuItemControlTypeId = 50011; 18 | public const int UIA_ProgressBarControlTypeId = 50012; 19 | public const int UIA_RadioButtonControlTypeId = 50013; 20 | public const int UIA_ScrollBarControlTypeId = 50014; 21 | public const int UIA_SliderControlTypeId = 50015; 22 | public const int UIA_SpinnerControlTypeId = 50016; 23 | public const int UIA_StatusBarControlTypeId = 50017; 24 | public const int UIA_TabControlTypeId = 50018; 25 | public const int UIA_TabItemControlTypeId = 50019; 26 | public const int UIA_TextControlTypeId = 50020; 27 | public const int UIA_ToolBarControlTypeId = 50021; 28 | public const int UIA_ToolTipControlTypeId = 50022; 29 | public const int UIA_TreeControlTypeId = 50023; 30 | public const int UIA_TreeItemControlTypeId = 50024; 31 | public const int UIA_CustomControlTypeId = 50025; 32 | public const int UIA_GroupControlTypeId = 50026; 33 | public const int UIA_ThumbControlTypeId = 50027; 34 | public const int UIA_DataGridControlTypeId = 50028; 35 | public const int UIA_DataItemControlTypeId = 50029; 36 | public const int UIA_DocumentControlTypeId = 50030; 37 | public const int UIA_SplitButtonControlTypeId = 50031; 38 | public const int UIA_WindowControlTypeId = 50032; 39 | public const int UIA_PaneControlTypeId = 50033; 40 | public const int UIA_HeaderControlTypeId = 50034; 41 | public const int UIA_HeaderItemControlTypeId = 50035; 42 | public const int UIA_TableControlTypeId = 50036; 43 | public const int UIA_TitleBarControlTypeId = 50037; 44 | public const int UIA_SeparatorControlTypeId = 50038; 45 | } 46 | 47 | internal abstract class UIA_PropertyIds 48 | { 49 | public const int UIA_RuntimeIdPropertyId = 30000; 50 | public const int UIA_BoundingRectanglePropertyId = 30001; 51 | public const int UIA_ProcessIdPropertyId = 30002; 52 | public const int UIA_ControlTypePropertyId = 30003; 53 | public const int UIA_LocalizedControlTypePropertyId = 30004; 54 | public const int UIA_NamePropertyId = 30005; 55 | public const int UIA_AcceleratorKeyPropertyId = 30006; 56 | public const int UIA_AccessKeyPropertyId = 30007; 57 | public const int UIA_HasKeyboardFocusPropertyId = 30008; 58 | public const int UIA_IsKeyboardFocusablePropertyId = 30009; 59 | public const int UIA_IsEnabledPropertyId = 30010; 60 | public const int UIA_AutomationIdPropertyId = 30011; 61 | public const int UIA_ClassNamePropertyId = 30012; 62 | public const int UIA_HelpTextPropertyId = 30013; 63 | public const int UIA_ClickablePointPropertyId = 30014; 64 | public const int UIA_CulturePropertyId = 30015; 65 | public const int UIA_IsControlElementPropertyId = 30016; 66 | public const int UIA_IsContentElementPropertyId = 30017; 67 | public const int UIA_LabeledByPropertyId = 30018; 68 | public const int UIA_IsPasswordPropertyId = 30019; 69 | public const int UIA_NativeWindowHandlePropertyId = 30020; 70 | public const int UIA_ItemTypePropertyId = 30021; 71 | public const int UIA_IsOffscreenPropertyId = 30022; 72 | public const int UIA_OrientationPropertyId = 30023; 73 | public const int UIA_FrameworkIdPropertyId = 30024; 74 | public const int UIA_IsRequiredForFormPropertyId = 30025; 75 | public const int UIA_ItemStatusPropertyId = 30026; 76 | public const int UIA_IsDockPatternAvailablePropertyId = 30027; 77 | public const int UIA_IsExpandCollapsePatternAvailablePropertyId = 30028; 78 | public const int UIA_IsGridItemPatternAvailablePropertyId = 30029; 79 | public const int UIA_IsGridPatternAvailablePropertyId = 30030; 80 | public const int UIA_IsInvokePatternAvailablePropertyId = 30031; 81 | public const int UIA_IsMultipleViewPatternAvailablePropertyId = 30032; 82 | public const int UIA_IsRangeValuePatternAvailablePropertyId = 30033; 83 | public const int UIA_IsScrollPatternAvailablePropertyId = 30034; 84 | public const int UIA_IsScrollItemPatternAvailablePropertyId = 30035; 85 | public const int UIA_IsSelectionItemPatternAvailablePropertyId = 30036; 86 | public const int UIA_IsSelectionPatternAvailablePropertyId = 30037; 87 | public const int UIA_IsTablePatternAvailablePropertyId = 30038; 88 | public const int UIA_IsTableItemPatternAvailablePropertyId = 30039; 89 | public const int UIA_IsTextPatternAvailablePropertyId = 30040; 90 | public const int UIA_IsTogglePatternAvailablePropertyId = 30041; 91 | public const int UIA_IsTransformPatternAvailablePropertyId = 30042; 92 | public const int UIA_IsValuePatternAvailablePropertyId = 30043; 93 | public const int UIA_IsWindowPatternAvailablePropertyId = 30044; 94 | public const int UIA_ValueValuePropertyId = 30045; 95 | public const int UIA_ValueIsReadOnlyPropertyId = 30046; 96 | public const int UIA_RangeValueValuePropertyId = 30047; 97 | public const int UIA_RangeValueIsReadOnlyPropertyId = 30048; 98 | public const int UIA_RangeValueMinimumPropertyId = 30049; 99 | public const int UIA_RangeValueMaximumPropertyId = 30050; 100 | public const int UIA_RangeValueLargeChangePropertyId = 30051; 101 | public const int UIA_RangeValueSmallChangePropertyId = 30052; 102 | public const int UIA_ScrollHorizontalScrollPercentPropertyId = 30053; 103 | public const int UIA_ScrollHorizontalViewSizePropertyId = 30054; 104 | public const int UIA_ScrollVerticalScrollPercentPropertyId = 30055; 105 | public const int UIA_ScrollVerticalViewSizePropertyId = 30056; 106 | public const int UIA_ScrollHorizontallyScrollablePropertyId = 30057; 107 | public const int UIA_ScrollVerticallyScrollablePropertyId = 30058; 108 | public const int UIA_SelectionSelectionPropertyId = 30059; 109 | public const int UIA_SelectionCanSelectMultiplePropertyId = 30060; 110 | public const int UIA_SelectionIsSelectionRequiredPropertyId = 30061; 111 | public const int UIA_GridRowCountPropertyId = 30062; 112 | public const int UIA_GridColumnCountPropertyId = 30063; 113 | public const int UIA_GridItemRowPropertyId = 30064; 114 | public const int UIA_GridItemColumnPropertyId = 30065; 115 | public const int UIA_GridItemRowSpanPropertyId = 30066; 116 | public const int UIA_GridItemColumnSpanPropertyId = 30067; 117 | public const int UIA_GridItemContainingGridPropertyId = 30068; 118 | public const int UIA_DockDockPositionPropertyId = 30069; 119 | public const int UIA_ExpandCollapseExpandCollapseStatePropertyId = 30070; 120 | public const int UIA_MultipleViewCurrentViewPropertyId = 30071; 121 | public const int UIA_MultipleViewSupportedViewsPropertyId = 30072; 122 | public const int UIA_WindowCanMaximizePropertyId = 30073; 123 | public const int UIA_WindowCanMinimizePropertyId = 30074; 124 | public const int UIA_WindowWindowVisualStatePropertyId = 30075; 125 | public const int UIA_WindowWindowInteractionStatePropertyId = 30076; 126 | public const int UIA_WindowIsModalPropertyId = 30077; 127 | public const int UIA_WindowIsTopmostPropertyId = 30078; 128 | public const int UIA_SelectionItemIsSelectedPropertyId = 30079; 129 | public const int UIA_SelectionItemSelectionContainerPropertyId = 30080; 130 | public const int UIA_TableRowHeadersPropertyId = 30081; 131 | public const int UIA_TableColumnHeadersPropertyId = 30082; 132 | public const int UIA_TableRowOrColumnMajorPropertyId = 30083; 133 | public const int UIA_TableItemRowHeaderItemsPropertyId = 30084; 134 | public const int UIA_TableItemColumnHeaderItemsPropertyId = 30085; 135 | public const int UIA_ToggleToggleStatePropertyId = 30086; 136 | public const int UIA_TransformCanMovePropertyId = 30087; 137 | public const int UIA_TransformCanResizePropertyId = 30088; 138 | public const int UIA_TransformCanRotatePropertyId = 30089; 139 | public const int UIA_IsLegacyIAccessiblePatternAvailablePropertyId = 30090; 140 | public const int UIA_LegacyIAccessibleChildIdPropertyId = 30091; 141 | public const int UIA_LegacyIAccessibleNamePropertyId = 30092; 142 | public const int UIA_LegacyIAccessibleValuePropertyId = 30093; 143 | public const int UIA_LegacyIAccessibleDescriptionPropertyId = 30094; 144 | public const int UIA_LegacyIAccessibleRolePropertyId = 30095; 145 | public const int UIA_LegacyIAccessibleStatePropertyId = 30096; 146 | public const int UIA_LegacyIAccessibleHelpPropertyId = 30097; 147 | public const int UIA_LegacyIAccessibleKeyboardShortcutPropertyId = 30098; 148 | public const int UIA_LegacyIAccessibleSelectionPropertyId = 30099; 149 | public const int UIA_LegacyIAccessibleDefaultActionPropertyId = 30100; 150 | public const int UIA_AriaRolePropertyId = 30101; 151 | public const int UIA_AriaPropertiesPropertyId = 30102; 152 | public const int UIA_IsDataValidForFormPropertyId = 30103; 153 | public const int UIA_ControllerForPropertyId = 30104; 154 | public const int UIA_DescribedByPropertyId = 30105; 155 | public const int UIA_FlowsToPropertyId = 30106; 156 | public const int UIA_ProviderDescriptionPropertyId = 30107; 157 | public const int UIA_IsItemContainerPatternAvailablePropertyId = 30108; 158 | public const int UIA_IsVirtualizedItemPatternAvailablePropertyId = 30109; 159 | public const int UIA_IsSynchronizedInputPatternAvailablePropertyId = 30110; 160 | 161 | public const int UIA_OptimizeForVisualContentPropertyId = 30111; 162 | public const int UIA_LiveSettingPropertyId = 30135; 163 | public const int UIA_IsPeripheralPropertyId = 30150; 164 | public const int UIA_PositionInSetPropertyId = 30152; 165 | public const int UIA_SizeOfSetPropertyId = 30153; 166 | public const int UIA_LevelPropertyId = 30154; 167 | public const int UIA_AnnotationTypesPropertyId = 30155; 168 | public const int UIA_LandmarkTypePropertyId = 30157; 169 | public const int UIA_LocalizedLandmarkTypePropertyId = 30158; 170 | public const int UIA_FullDescriptionPropertyId = 30159; 171 | public const int UIA_HeadingLevelPropertyId = 30173; 172 | public const int UIA_IsDialogPropertyId = 30174; 173 | } 174 | 175 | internal abstract class UIA_PatternIds 176 | { 177 | public const int UIA_InvokePatternId = 10000; 178 | public const int UIA_SelectionPatternId = 10001; 179 | public const int UIA_ValuePatternId = 10002; 180 | public const int UIA_RangeValuePatternId = 10003; 181 | public const int UIA_ScrollPatternId = 10004; 182 | public const int UIA_ExpandCollapsePatternId = 10005; 183 | public const int UIA_GridPatternId = 10006; 184 | public const int UIA_GridItemPatternId = 10007; 185 | public const int UIA_MultipleViewPatternId = 10008; 186 | public const int UIA_WindowPatternId = 10009; 187 | public const int UIA_SelectionItemPatternId = 10010; 188 | public const int UIA_DockPatternId = 10011; 189 | public const int UIA_TablePatternId = 10012; 190 | public const int UIA_TableItemPatternId = 10013; 191 | public const int UIA_TextPatternId = 10014; 192 | public const int UIA_TogglePatternId = 10015; 193 | public const int UIA_TransformPatternId = 10016; 194 | public const int UIA_ScrollItemPatternId = 10017; 195 | public const int UIA_LegacyIAccessiblePatternId = 10018; 196 | public const int UIA_ItemContainerPatternId = 10019; 197 | public const int UIA_VirtualizedItemPatternId = 10020; 198 | public const int UIA_SynchronizedInputPatternId = 10021; 199 | public const int UIA_ObjectModelPatternId = 10022; 200 | public const int UIA_AnnotationPatternId = 10023; 201 | public const int UIA_TextPattern2Id = 10024; 202 | public const int UIA_StylesPatternId = 10025; 203 | public const int UIA_SpreadsheetPatternId = 10026; 204 | public const int UIA_SpreadsheetItemPatternId = 10027; 205 | public const int UIA_TransformPattern2Id = 10028; 206 | public const int UIA_TextChildPatternId = 10029; 207 | public const int UIA_DragPatternId = 10030; 208 | public const int UIA_DropTargetPatternId = 10031; 209 | public const int UIA_TextEditPatternId = 10032; 210 | public const int UIA_CustomNavigationPatternId = 10033; 211 | public const int UIA_SelectionPattern2Id = 10034; 212 | } 213 | 214 | internal abstract class UIA_EventIds 215 | { 216 | public const int UIA_ToolTipOpenedEventId = 20000; 217 | public const int UIA_ToolTipClosedEventId = 20001; 218 | public const int UIA_StructureChangedEventId = 20002; 219 | public const int UIA_MenuOpenedEventId = 20003; 220 | public const int UIA_AutomationPropertyChangedEventId = 20004; 221 | public const int UIA_AutomationFocusChangedEventId = 20005; 222 | public const int UIA_AsyncContentLoadedEventId = 20006; 223 | public const int UIA_MenuClosedEventId = 20007; 224 | public const int UIA_LayoutInvalidatedEventId = 20008; 225 | public const int UIA_Invoke_InvokedEventId = 20009; 226 | public const int UIA_SelectionItem_ElementAddedToSelectionEventId = 20010; 227 | public const int UIA_SelectionItem_ElementRemovedFromSelectionEventId = 20011; 228 | public const int UIA_SelectionItem_ElementSelectedEventId = 20012; 229 | public const int UIA_Selection_InvalidatedEventId = 20013; 230 | public const int UIA_Text_TextSelectionChangedEventId = 20014; 231 | public const int UIA_Text_TextChangedEventId = 20015; 232 | public const int UIA_Window_WindowOpenedEventId = 20016; 233 | public const int UIA_Window_WindowClosedEventId = 20017; 234 | public const int UIA_MenuModeStartEventId = 20018; 235 | public const int UIA_MenuModeEndEventId = 20019; 236 | public const int UIA_InputReachedTargetEventId = 20020; 237 | public const int UIA_InputReachedOtherElementEventId = 20021; 238 | public const int UIA_InputDiscardedEventId = 20022; 239 | } 240 | 241 | internal abstract class UIA_TextAttributeIds 242 | { 243 | public const int UIA_AnimationStyleAttributeId = 40000; 244 | public const int UIA_BackgroundColorAttributeId = 40001; 245 | public const int UIA_BulletStyleAttributeId = 40002; 246 | public const int UIA_CapStyleAttributeId = 40003; 247 | public const int UIA_CultureAttributeId = 40004; 248 | public const int UIA_FontNameAttributeId = 40005; 249 | public const int UIA_FontSizeAttributeId = 40006; 250 | public const int UIA_FontWeightAttributeId = 40007; 251 | public const int UIA_ForegroundColorAttributeId = 40008; 252 | public const int UIA_HorizontalTextAlignmentAttributeId = 40009; 253 | public const int UIA_IndentationFirstLineAttributeId = 40010; 254 | public const int UIA_IndentationLeadingAttributeId = 40011; 255 | public const int UIA_IndentationTrailingAttributeId = 40012; 256 | public const int UIA_IsHiddenAttributeId = 40013; 257 | public const int UIA_IsItalicAttributeId = 40014; 258 | public const int UIA_IsReadOnlyAttributeId = 40015; 259 | public const int UIA_IsSubscriptAttributeId = 40016; 260 | public const int UIA_IsSuperscriptAttributeId = 40017; 261 | public const int UIA_MarginBottomAttributeId = 40018; 262 | public const int UIA_MarginLeadingAttributeId = 40019; 263 | public const int UIA_MarginTopAttributeId = 40020; 264 | public const int UIA_MarginTrailingAttributeId = 40021; 265 | public const int UIA_OutlineStylesAttributeId = 40022; 266 | public const int UIA_OverlineColorAttributeId = 40023; 267 | public const int UIA_OverlineStyleAttributeId = 40024; 268 | public const int UIA_StrikethroughColorAttributeId = 40025; 269 | public const int UIA_StrikethroughStyleAttributeId = 40026; 270 | public const int UIA_TabsAttributeId = 40027; 271 | public const int UIA_TextFlowDirectionsAttributeId = 40028; 272 | public const int UIA_UnderlineColorAttributeId = 40029; 273 | public const int UIA_UnderlineStyleAttributeId = 40030; 274 | public const int UIA_AnnotationTypesAttributeId = 40031; 275 | public const int UIA_AnnotationObjectsAttributeId = 40032; 276 | public const int UIA_StyleNameAttributeId = 40033; 277 | public const int UIA_StyleIdAttributeId = 40034; 278 | public const int UIA_LinkAttributeId = 40035; 279 | public const int UIA_IsActiveAttributeId = 40036; 280 | public const int UIA_SelectionActiveEndAttributeId = 40037; 281 | public const int UIA_CaretPositionAttributeId = 40038; 282 | public const int UIA_CaretBidiModeAttributeId = 40039; 283 | public const int UIA_LineSpacingAttributeId = 40040; 284 | public const int UIA_BeforeParagraphSpacingAttributeId = 40041; 285 | public const int UIA_AfterParagraphSpacingAttributeId = 40042; 286 | public const int UIA_SayAsInterpretAsAttributeId = 40043; 287 | } 288 | 289 | internal abstract class UIA_ScrollPattern 290 | { 291 | public const int UIA_ScrollPatternNoScroll = -1; 292 | } 293 | 294 | internal static class UIA_HeadingLevelIds 295 | { 296 | public const int HeadingLevel_None = 80050; 297 | public const int HeadingLevel1 = 80051; 298 | public const int HeadingLevel2 = 80052; 299 | public const int HeadingLevel3 = 80053; 300 | public const int HeadingLevel4 = 80054; 301 | public const int HeadingLevel5 = 80055; 302 | public const int HeadingLevel6 = 80056; 303 | public const int HeadingLevel7 = 80057; 304 | public const int HeadingLevel8 = 80058; 305 | public const int HeadingLevel9 = 80059; 306 | } 307 | 308 | internal static class UIA_LandmarkTypeIds 309 | { 310 | public const int UIA_CustomLandmarkTypeId = 80000; 311 | public const int UIA_FormLandmarkTypeId = 80001; 312 | public const int UIA_MainLandmarkTypeId = 80002; 313 | public const int UIA_NavigationLandmarkTypeId = 80003; 314 | public const int UIA_SearchLandmarkTypeId = 80004; 315 | } 316 | 317 | internal static class UIA_ChangeIds 318 | { 319 | public const int UIA_SummaryChangeId = 90000; 320 | } 321 | } -------------------------------------------------------------------------------- /src/AutomationSpy/Lib/Interop.UIAutomationClient.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddeltasolutions/Automation-Spy/fa179d621f4e94636daed46169f8340889849601/src/AutomationSpy/Lib/Interop.UIAutomationClient.dll -------------------------------------------------------------------------------- /src/AutomationSpy/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 177 | 178 | 179 | 180 | 181 | 182 | 187 | 192 | 193 | 198 | 199 | Control View 200 | Raw View 201 | Content View 202 | 203 | 205 | 206 | -------------------------------------------------------------------------------- /src/AutomationSpy/MoreAttributes.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Attributes for this Text Range: 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 163 | 164 | 165 | 166 | 167 | 168 |