Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9366

C# - AutomationElementの情報を取得するツールをつくった(Windows10)

$
0
0

機能

クリックした座標にあるコントロールの情報(実行パスとAutomationElementInformation)を取得します。
(ウィンドウハンドルを取得して、該当座標を含む、子AutomationElementを再帰的に探します。重なっている場合はどれか1つになります。)

AutomationElementの使い方は、手前味噌ですが
Windows10でBASIC認証画面にIDとパスワードを自動入力するソフトを作ったなどを参照ください。

注意事項

  • マルチスクリーン環境での動作は未確認です。
  • マウスのグローバルフックを使用しています。

スクリーンショット

例:getボタンを押して、コマンドプロンプトのタイトルバーをクリックした場合。
image.png

ソースコード

usingSystem;usingSystem.Runtime.InteropServices;usingSystem.Text.RegularExpressions;usingSystem.Threading;usingSystem.Windows.Automation;usingSystem.Windows.Forms;publicstaticclassNativeMethods{[StructLayout(LayoutKind.Sequential)]publicstructPOINT{publicintx;publicinty;}publicconstintWH_MOUSE_LL=14;publicdelegateIntPtrHookProc(intcode,IntPtrwParam,IntPtrlParam);[DllImport("user32.dll",SetLastError=true)]publicstaticexternIntPtrSetWindowsHookEx(intidHook,HookProccallback,IntPtrhInstance,intthreadId);[DllImport("user32.dll",SetLastError=true)]publicstaticexternboolUnhookWindowsHookEx(IntPtrhHook);[DllImport("user32.dll")]publicstaticexternIntPtrCallNextHookEx(IntPtrhHook,intnCode,IntPtrwParam,IntPtrlParam);publicconstintWM_MOUSEMOVE=0x0200;publicconstintWM_LBUTTONDOWN=0x0201;publicconstintWM_LBUTTONUP=0x0202;publicconstintWM_RBUTTONDOWN=0x0204;publicconstintWM_RBUTTONUP=0x0205;publicconstintWM_MOUSEWHEEL=0x020A;publicconstintWM_MOUSEHWHEEL=0x020E;[DllImport("user32.dll",SetLastError=true)]publicstaticexternIntPtrWindowFromPoint(POINTpoint);[DllImport("user32.dll",SetLastError=true)]publicstaticexternIntPtrGetAncestor(IntPtrhWnd,intgaFlags);publicconstintGA_PARENT=1;publicconstintGA_ROOT=2;publicconstintGA_ROOTOWNER=3;[DllImport("User32.dll")]publicstaticexternIntPtrGetDC(IntPtrhwnd);[DllImport("User32.dll")]publicstaticexternvoidReleaseDC(IntPtrhwnd,IntPtrdc);[DllImport("user32.dll",SetLastError=true)]publicstaticexternintGetWindowThreadProcessId(IntPtrhWnd,outintlpdwProcessId);[DllImport("user32.dll")][return:MarshalAs(UnmanagedType.Bool)]publicstaticexternboolSetProcessDPIAware();}publicclassAutomationTest:Form{IntPtr_hHook;NativeMethods.HookProc_handler;GCHandle_hookProcHandle;NativeMethods.POINT_lastPoint;bool_hookExitReq;System.Windows.Forms.Timertimer;Buttonbtn;TextBoxtxtProc;ListViewlsv;AutomationTest(){NativeMethods.SetProcessDPIAware();timer=newSystem.Windows.Forms.Timer();timer.Interval=10;timer.Tick+=(s,e)=>{Timer_Tick();};btn=newButton(){Text="get"};btn.Click+=(s,e)=>{Btn_Click();};Controls.Add(btn);txtProc=newTextBox(){ReadOnly=true,Location=newSystem.Drawing.Point(100,0)};txtProc.KeyDown+=(sender,e)=>{if(e.Control&&e.KeyCode==Keys.A){txtProc.SelectAll();}};Controls.Add(txtProc);lsv=newListView(){Location=newSystem.Drawing.Point(0,40),FullRowSelect=true,GridLines=true,HideSelection=false,MultiSelect=false,View=View.Details};lsv.MouseDoubleClick+=Lsv_MouseDoubleClick;lsv.Columns.AddRange(newColumnHeader[]{newColumnHeader(){Text="ClassName",Width=150},newColumnHeader(){Text="AutomationId",Width=80},newColumnHeader(){Text="ControlType",Width=100},newColumnHeader(){Text="FrameworkId",Width=50},newColumnHeader(){Text="Name",Width=150},newColumnHeader(){Text="ItemType",Width=50},newColumnHeader(){Text="X",Width=50,TextAlign=HorizontalAlignment.Right},newColumnHeader(){Text="Y",Width=50,TextAlign=HorizontalAlignment.Right},newColumnHeader(){Text="Width",Width=50,TextAlign=HorizontalAlignment.Right},newColumnHeader(){Text="Height",Width=50,TextAlign=HorizontalAlignment.Right},});Controls.Add(lsv);this.Text="AutomationElement Information Getter";this.ClientSize=newSystem.Drawing.Size(700,500);FormClosed+=(s,e)=>{UnHook();};Load+=(s,e)=>{MyResize();};Resize+=(s,e)=>{MyResize();};ResizeEnd+=(s,e)=>{MyResize();};}voidMyResize(){intw=ClientSize.Width-txtProc.Left;inth=ClientSize.Height-lsv.Top;if(w<50){w=50;}if(h<50){h=50;}lsv.Size=newSystem.Drawing.Size(ClientSize.Width,h);txtProc.Width=w;}voidTimer_Tick(){UnHook();if(!timer.Enabled){return;}timer.Stop();btn.Enabled=true;varp=newSystem.Windows.Point(_lastPoint.x,_lastPoint.y);IntPtrhWnd=NativeMethods.WindowFromPoint(_lastPoint);hWnd=NativeMethods.GetAncestor(hWnd,NativeMethods.GA_ROOT);varelem=AutomationElement.FromHandle(hWnd);{intpid;NativeMethods.GetWindowThreadProcessId(hWnd,outpid);varproc=System.Diagnostics.Process.GetProcessById(pid);txtProc.Text=proc.MainModule.FileName;}if(elem!=null){lsv.BeginUpdate();try{AutomationElement.AutomationElementInformationelemInfo;do{try{elemInfo=elem.Current;}catch(ElementNotAvailableException){return;}lsv.Items.Add(AeToListItem(elemInfo));elem=FindNextElementFromPoint(elem,p);}while(elem!=null);DrawPointAndRectToScreen(p,elemInfo.BoundingRectangle);}finally{lsv.EndUpdate();}}}AutomationElementFindNextElementFromPoint(AutomationElementelem,System.Windows.Pointp){varchildElements=elem.FindAll(TreeScope.Children,Condition.TrueCondition);foreach(AutomationElementchildEleminchildElements){AutomationElement.AutomationElementInformationelemInfo;try{elemInfo=childElem.Current;}catch(ElementNotAvailableException){returnnull;}if(elemInfo.BoundingRectangle.Contains(p)){returnchildElem;}}returnnull;}ListViewItemAeToListItem(AutomationElement.AutomationElementInformationa){System.Windows.Rectr=a.BoundingRectangle;returnnewListViewItem(newstring[]{a.ClassName,a.AutomationId,a.ControlType.ToString(),a.FrameworkId,a.Name,a.ItemType,r.X.ToString(),r.Y.ToString(),r.Width.ToString(),r.Height.ToString()});}voidBtn_Click(){try{_hookExitReq=false;SetHook();}catch(System.ComponentModel.Win32Exceptione){MessageBox.Show(e.ToString());return;}btn.Enabled=false;lsv.Items.Clear();}voidLsv_MouseDoubleClick(objectsender,MouseEventArgse){ListViewHitTestInfoinfo=lsv.HitTest(e.Location);if(info.SubItem!=null){SubFormf=newSubForm(info.SubItem.Text);f.ShowDialog();}}voidDrawPointAndRectToScreen(System.Windows.Pointp,System.Windows.Rectrect){IntPtrdesktopDC=NativeMethods.GetDC(IntPtr.Zero);if(desktopDC==IntPtr.Zero){// failedreturn;}try{varpen=newSystem.Drawing.Pen(System.Drawing.Color.Blue,6.0f);using(varg=System.Drawing.Graphics.FromHdc(desktopDC)){g.DrawLine(pen,(float)(p.X-5),(float)(p.Y-5),(float)(p.X+5),(float)(p.Y+5));g.DrawLine(pen,(float)(p.X-5),(float)(p.Y+5),(float)(p.X+5),(float)(p.Y-5));g.DrawRectangle(pen,(float)rect.X,(float)rect.Y,(float)rect.Width,(float)rect.Height);}}finally{NativeMethods.ReleaseDC(IntPtr.Zero,desktopDC);}}voidSetHook(){IntPtrmodule=IntPtr.Zero;_handler=CallbackProc;_hookProcHandle=GCHandle.Alloc(_handler);_hHook=NativeMethods.SetWindowsHookEx(NativeMethods.WH_MOUSE_LL,_handler,module,0);if(_hHook==IntPtr.Zero){// failedinterrorCode=Marshal.GetLastWin32Error();_hookProcHandle.Free();_handler=null;thrownewSystem.ComponentModel.Win32Exception(errorCode);}}voidUnHook(){if(_hHook!=IntPtr.Zero){NativeMethods.UnhookWindowsHookEx(_hHook);_hHook=IntPtr.Zero;_hookProcHandle.Free();_handler=null;}}IntPtrCallbackProc(intnCode,IntPtrwParam,IntPtrlParam){if(nCode<0||_hookExitReq){returnNativeMethods.CallNextHookEx(_hHook,nCode,wParam,lParam);}else{if((long)wParam==NativeMethods.WM_MOUSEMOVE){returnNativeMethods.CallNextHookEx(_hHook,nCode,wParam,lParam);// 注意:WM_MOUSEMOVE をキャンセルすると、カーソル表示が更新されない}else{if((long)wParam==NativeMethods.WM_LBUTTONDOWN||(long)wParam==NativeMethods.WM_RBUTTONDOWN){_hookExitReq=true;varp=Cursor.Position;_lastPoint=newNativeMethods.POINT(){x=p.X,y=p.Y};timer.Start();}// cancelreturnnewIntPtr(1);}}}[STAThread]staticvoidMain(string[]args){Application.Run(newAutomationTest());}}internalclassSubForm:Form{internalSubForm(stringtext){vartxt=newTextBox(){Text=text,Multiline=true,ScrollBars=ScrollBars.Both,Dock=DockStyle.Fill};txt.KeyDown+=(sender,e)=>{if(e.Control&&e.KeyCode==Keys.A){txt.SelectAll();}};Controls.Add(txt);}}

コンパイルバッチ

compile.bat
csc ^
 /r:C:\Windows\Microsoft.NET\assembly\GAC_MSIL\UIAutomationClient\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationClient.dll ^
 /r:C:\Windows\Microsoft.NET\assembly\GAC_MSIL\UIAutomationTypes\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationTypes.dll ^
 /r:C:\Windows\Microsoft.NET\assembly\GAC_MSIL\WindowsBase\v4.0_4.0.0.0__31bf3856ad364e35\WindowsBase.dll ^
 %*

Viewing all articles
Browse latest Browse all 9366

Latest Images

Trending Articles