UIA是UI Automation,是微软提供的一套自动化接口。具体是什么意思。通俗的将,就是微软的标准控件都实现一个接口,使使用UIA编程的程序可以控制这个控件。如果是自绘的控件实现相应接口也可以让UIA的程序控制。
举例来说。
你写个mfc程序,有个button,内容是弹一个MessageBox。你想领写个程序去间接调用这个button。学外挂的熟悉,就是注入找call。但我们使用UIA可以很轻松实现。
UIA编程msdn上也很详细,不过大部分都是.net,c++例子很少,而且是英文。我这里就简单实现个例子。
这次例子是调用这个Button。
UIA把所有可调用控件元素都是一个树形式保存的,具体可以以用Inspect.exe查看,这个sdk带的小软件。你打开后把鼠标移到相应位置可以得到该控件相应信息。如果不是微软标准控件而且没有实现他的接口就没办法了。如图就是,我们要调用button4按钮。
第一步 需要 实现IUIAutomation 接口
他可以用于以下
1,注册事件
2,建立条件,使减少搜索控件元素范围。
3,直接从root节点获得控件元素。
4,建立元素 树遍历
5,转换数据类型
代码
CoCreateInstance(CLSID_CUIAutomation, NULL, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&g_pIUAutomation));
这个接口是老大。IUIAutomation一些方法可以直接获得控件元素
IUIAutomation::GetFocusedElement , IUIAutomation::GetRootElement
然后可以用IUIAutomationElement::FindFirst 和FindAll. 搜索自控件。
第二步 实现IUIAutomationElement,
可以理解为每个控件都可以是IUIAutomationElement。我们调用button就用他的ivoke方法
IUIAutomationCondition 是条件搜索。控件一大堆,想搜到我们想要的靠他。
#include "stdafx.h"
#include <uiautomation.h>
IUIAutomation *g_pIUAutomation=NULL;
//我们button 的名字 可以通过inspect找到
WCHAR wcButtonName1[]=L"Button4";
HWND g_hwd=NULL;
int _tmain(int argc, _TCHAR* argv[])
{
//因为是com所以你懂的
HRESULT hr=CoInitialize(NULL);
if(SUCCEEDED(hr))
{
IUIAutomationElement* pRoot = NULL;
IUIAutomationElement* pFound = NULL;
IUIAutomationCondition* pCondition=NULL;
IUIAutomationInvokePattern *pPattern = NULL;
do
{
//初始化IUAutomation实例
hr = CoCreateInstance(CLSID_CUIAutomation, NULL, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&g_pIUAutomation));
if(FAILED(hr))
{
printf("create IUAutomation instance failed ");
break;
}
//创建条件搜索
VARIANT varName;
varName.vt=VT_BSTR;
varName.bstrVal=SysAllocString(wcButtonName1);
//这个是根据句柄获得该 句柄下所有的元素,我注释掉了
// hr=g_pIUAutomation->ElementFromHandle(g_hwd,&pRoot);
//获得根目录下,就是从开始 下所有控件元素
hr=g_pIUAutomation->GetRootElement(&pRoot);
if (FAILED(hr) || pRoot == NULL)
{
printf("get root element failed/n");
break;
}
//创建条件搜索,根据我们button名字搜索
hr = g_pIUAutomation->CreatePropertyCondition(UIA_NamePropertyId, varName, &pCondition);
if(FAILED(hr))
{
printf("create condition failed/n");
break;
}
pRoot->FindFirst(TreeScope_Subtree, pCondition, &pFound);
// pRoot->FindFirst(TreeScope_Children, pCondition, &pFound);
//调用invoke
hr = pFound->GetCurrentPatternAs(UIA_InvokePatternId, IID_PPV_ARGS(&pPattern));
hr = pPattern->Invoke();
} while (FALSE);
if(g_pIUAutomation!=NULL)
{
g_pIUAutomation->Release();
g_pIUAutomation=NULL;
}
if(pRoot!=NULL)
{
pRoot->Release();
pRoot=NULL;
}
if(pFound!=NULL)
{
pFound->Release();
pFound=NULL;
}
if(pCondition!=NULL)
{
pCondition->Release();
pCondition=NULL;
}
if(pPattern!=NULL)
{
pPattern->Release();
pPattern=NULL;
}
CoUninitialize();
}
else
{
printf("initialize com failed/n");
}
return 0;
}
uia的功能远远不只这些,还可以操纵list 等复杂控件,特别操作网页元素。当然前提是ie内核下的。Google浏览器是不行的。可以实现自动网页上的很多功能。比如订票的自动化了。总之这是套很好玩的接口。
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法