UIAutomation 元素为远程桌面连接上的边界矩形返回错误值

Posted

技术标签:

【中文标题】UIAutomation 元素为远程桌面连接上的边界矩形返回错误值【英文标题】:UIAutomation Element returning wrong values for Bounding Rectangle on Remote Desktop Connection 【发布时间】:2021-06-14 19:46:07 【问题描述】:

问题陈述是我们所需的应用程序将在远程计算机上运行,​​我们用户将通过远程桌面连接使用该计算机。这个想法是只截取在该机器上运行的应用程序区域的屏幕截图。我们能够通过 spyxx 获取应用程序窗口的矩形边界,窗口句柄返回正确的窗口并且 processId 是可访问的,但是当我们尝试获取矩形边界时,我们得到了一些错误的坐标。任何帮助将不胜感激。

var winhandle = NativeMethods.FindWindow("RAIL_WINDOW", null);
            if (winhandle != IntPtr.Zero)
            
                var mainEMRWindow = AutomationElement.FromHandle(winhandle);
                if (mainEMRWindow != null)
                
                   Console.WriteLine("Bounding Rectangle: " + mainEMRWindow.Current.BoundingRectangle.Left + "," + mainEMRWindow.Current.BoundingRectangle.Top + "," + mainEMRWindow.Current.BoundingRectangle.Right + "," + mainEMRWindow.Current.BoundingRectangle.Bottom);
                                           RECT clientRect = GetClientRect(winhandle);

                    Console.WriteLine("Client Rect: " + "Left: " + clientRect.Left.ToString() + "," + "Top: " + clientRect.Top.ToString() + "," + "Right: " + clientRect.Right.ToString() + "," + "Bottom: " + clientRect.Bottom.ToString());

                    Rectangle rc;
                    GetWindowRect(winhandle, out rc);

                    Console.WriteLine("Window Rect: " + "Left: " + rc.Left.ToString() + "," + "Top: " + rc.Top.ToString() + "," + "Right: " + rc.Right.ToString() + "," + "Bottom: " + rc.Bottom.ToString());
                
            

我还将附上应用程序和代码的屏幕截图。 DPI 感知是每个监视器。在这种情况下,正确的边界矩形是左 65、上 10、右 1793 和下 1020,但我得到的边界矩形是 105、568、1108,594,这是错误的。

【问题讨论】:

您忘记提及您获得的 错误 度量是什么以及通过什么方法:UI 自动化、GetWindowRect()GetClientRect()(当然返回 ClientRectangle 而不是Window Bounds)以及这些度量与您在 Inspect 中看到的有何不同(后者是否被视为 right 值?)。请注意,这些函数不是 Dpi Aware。试试DwmGetWindowAttribute()。从here 获取代码。您也没有提及此应用程序的 DpiAwareness 状态。 DPI Aware 是每个监视器,附加了错误的测量屏幕截图,我需要获取矩形边界。我还将尝试您提供的解决方案,并且一定会向您更新我的发现。 不要调用 FindWindow,而是使用例如 FindWindowEx,或者,由于您正在使用 UI 自动化,请使用自动化方法。例如,var railWindow = AutomationElement.RootElement.FindFirst(TreeScope.Children, new AndCondition(new[] new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window), new PropertyCondition(AutomationElement.ClassNameProperty, "RAIL_WINDOW")));。你得到的度量似乎属于另一个(相当小的)窗口。 这个对我有用。谢谢@Jimi。 【参考方案1】:

@Jimi 完全正确。我得到了一些错误的窗口度量,但来自相同的进程和相同的窗口句柄。使用这个var railWindow = AutomationElement.RootElement.FindFirst(TreeScope.Children, new AndCondition(new[] new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window), new PropertyCondition(AutomationElement.ClassNameProperty, "RAIL_WINDOW"))); 对我有用

【讨论】:

以上是关于UIAutomation 元素为远程桌面连接上的边界矩形返回错误值的主要内容,如果未能解决你的问题,请参考以下文章

WIN7 远程桌面不能连接

怎么使用远程连接到虚拟机上

windows服务器如何开启远程桌面

远程桌面是什么 Windows电脑用什么远程桌面工具

UIPATH_远程桌面

Windows Server 2008无法远程连接