首页 > 代码库 > Client-Side UI Automation Provider - WinForm Sample

Client-Side UI Automation Provider - WinForm Sample

Client-Side UI Automation Provider -  WinForm Sample

2014-09-15

引用程序集

实现提供程序接口

分发客户端提供程序

注册和配置客户端提供程序

WinForm Sample

参考

引用程序集[1]


 返回

  • UIAutomationClient.dll
  • UIAutomationProviders.dll
  • UIAutomationTypes.dll 

实现提供程序接口[2]


 返回

以下示列实现提供程序接口:IRawElementProviderSimple

 1     class WindowProvider : IRawElementProviderSimple 2     { 3         IntPtr providerHwnd; 4         public WindowProvider(IntPtr hwnd) 5         { 6             providerHwnd = hwnd; 7         } 8         internal static IRawElementProviderSimple Create( 9             IntPtr hwnd, int idChild, int idObject)10         {11             System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("WinFormServer");12             if (processes.Length == 0)13                 return null;14             //Check if the target is specified process15             //If yes, create and run provider instance16             if (processes[0].MainWindowHandle != hwnd)17                 return null;18             else19                 return new WindowProvider(hwnd);20         }21         ProviderOptions IRawElementProviderSimple.ProviderOptions22         {23             get24             {25                 //Return ClientSideProvider as the implementation is in client26                 return ProviderOptions.ClientSideProvider;27             }28         }29         IRawElementProviderSimple IRawElementProviderSimple.HostRawElementProvider30         {31             get32             {33                 return AutomationInteropProvider.HostProviderFromHandle(providerHwnd);34             }35         }36         object IRawElementProviderSimple.GetPropertyValue(int aid)37         {38             if (AutomationProperty.LookupById(aid) ==39                 AutomationElementIdentifiers.NameProperty)40             {41                 //Our UIA.Name property implementation42                 //In production code, usually it uses Win32 or MSAA to get real information43                 return "UIA Client Implementation";44             }45             else46             {47                 return null;48             }49         }50         object IRawElementProviderSimple.GetPatternProvider(int iid)51         {52             //Return null means it does not support any Pattern Provider53             return null;54         }55     }
View Code

 

分发客户端提供程序[1][2]


 返回

UI 自动化应在托管代码程序集中查找客户端提供程序。该程序集中的命名空间应与该程序集同名。例如,称为UIAClientProvider.dll 的程序集应包含UIAClientProvider命名空间。 在该命名空间内创建 UIAutomationClientSideProviders 类。 在静态 ClientSideProviderDescriptionTable 字段的实现中,创建用于描述该提供程序的 ClientSideProviderDescription 结构数组。

ClientSideProviderDescription 结构数组将指定以下属性:

  • 一个回调函数,用于创建提供程序对象。 
  • 提供程序支持的控件的类名。 
  • 提供程序支持的应用程序的映像名(通常是可执行文件的全名)。 
  • 控制如何根据目标应用程序中的窗口类对类名进行匹配的标志。 

最后两个参数是可选的。  如果客户端希望对不同的应用程序使用不同的提供程序,则可以指定目标应用程序的映像名。 例如,客户端可以对支持多视图模式的已知应用程序中的 Win32 列表视图控件使用一个提供程序,而对不支持多视图模式的另一个已知应用程序中的类似控件使用另一个提供程序

1     class UIAutomationClientSideProviders2     {3         public static ClientSideProviderDescription[] ClientSideProviderDescriptionTable = 4             { new ClientSideProviderDescription(               5                 WindowProvider.Create,6                 null) };7     }
View Code

 

注册和配置客户端提供程序[1][2]


 返回

动态链接库 (DLL) 中的客户端提供程序通过调用 RegisterClientSideProviderAssembly 进行加载。  无需进一步的操作,客户端应用程序便可以使用这些提供程序。

在客户端自己的代码中实现的提供程序通过使用 RegisterClientSideProviders 进行注册。  此方法将 ClientSideProviderDescription 结构数组用作参数。

ClientSettings.RegisterClientSideProviders(UIAutomationClientSideProviders.ClientSideProviderDescriptionTable);

 

WinForm Sample[2]


 返回

创建Console Application:UIAClientProvider,代码如下:

 1 using System; 2 using System.Windows.Automation.Provider; 3 using System.Windows.Automation; 4  5 namespace UIAClientProvider 6 { 7     class Program 8     { 9         static void Main(string[] args)10         {11             ClientProviderSample.ClientProviderTest();12         }13     }14 15     public class ClientProviderSample16     {17         public static void ClientProviderTest()18         {19             //Calling RegisterClientSideProviders API to register out Client provider20             //Client Provider’s type information is stored in ClientSideProviderDescriptionTable Array21             ClientSettings.RegisterClientSideProviders(UIAutomationClientSideProviders.ClientSideProviderDescriptionTable);22             //Obtain main window of test target23             System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("WinFormServer");24             if (processes.Length == 0)25                 return;26             IntPtr hwnd = processes[0].MainWindowHandle;27             //Get UIA object of the test target main window28             AutomationElement elementWindow = AutomationElement.FromHandle(hwnd);29             //Read UIA.Name property30             Console.WriteLine(elementWindow.Current.Name);31             Console.WriteLine();32             Console.WriteLine("Press any key to exit.");33             Console.ReadLine();34         }35     }36     class UIAutomationClientSideProviders37     {38         public static ClientSideProviderDescription[] ClientSideProviderDescriptionTable = 39             { new ClientSideProviderDescription(               40                 WindowProvider.Create,41                 null) };42     }43     class WindowProvider : IRawElementProviderSimple44     {45         IntPtr providerHwnd;46         public WindowProvider(IntPtr hwnd)47         {48             providerHwnd = hwnd;49         }50         internal static IRawElementProviderSimple Create(51             IntPtr hwnd, int idChild, int idObject)52         {53             System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("WinFormServer");54             if (processes.Length == 0)55                 return null;56             //Check if the target is specified process57             //If yes, create and run provider instance58             if (processes[0].MainWindowHandle != hwnd)59                 return null;60             else61                 return new WindowProvider(hwnd);62         }63         ProviderOptions IRawElementProviderSimple.ProviderOptions64         {65             get66             {67                 //Return ClientSideProvider as the implementation is in client68                 return ProviderOptions.ClientSideProvider;69             }70         }71         IRawElementProviderSimple IRawElementProviderSimple.HostRawElementProvider72         {73             get74             {75                 return AutomationInteropProvider.HostProviderFromHandle(providerHwnd);76             }77         }78         object IRawElementProviderSimple.GetPropertyValue(int aid)79         {80             if (AutomationProperty.LookupById(aid) ==81                 AutomationElementIdentifiers.NameProperty)82             {83                 //Our UIA.Name property implementation84                 //In production code, usually it uses Win32 or MSAA to get real information85                 return "UIA Client Implementation";86             }87             else88             {89                 return null;90             }91         }92         object IRawElementProviderSimple.GetPatternProvider(int iid)93         {94             //Return null means it does not support any Pattern Provider95             return null;96         }97     }98 }
View Code

创建一个简单的WinForm Application: WinFormServer,代码如下:

 1 using System; 2 using System.Windows.Forms; 3  4 namespace WinFormServer 5 { 6     public partial class Form1 : Form 7     { 8         public Form1() 9         {10             InitializeComponent();11 12             this.Name = "testForm";13             this.Text = "ClientUIADemo";14 15         }16     }17 }
View Code

操作:

打开WinFormServer.exe。

运行UIAClientProvider。

参考

[1] 客户端 UI 自动化提供程序的实现

[2] UI Automation -- Under the Hood

Client-Side UI Automation Provider - WinForm Sample