Windows ui自动化和远程桌面连接问题

时间:2018-09-06 06:47:37

标签: c# windows automation rdp rpa

在通过chrome浏览器自动执行文件上传过程时,我遇到了问题。 我已经处理了“选择文件窗口”弹出窗口。我使用以下批处理文件从远程桌面连接注销。

for /f "skip=1 tokens=3" %%s in ('query user %USERNAME%') do (
  %windir%\System32\tscon.exe %%s /dest:console
)

我已经在Windows组策略中的管理模板> Windows组件>远程桌面会话主机>会话​​时间限制”下禁用了所有设置。

我已使用以下代码处理Windows文件上传对话框

    var title = "Open";
                var fileTextBoxName = "File name:";
                var openButtonName = "File name:";

                //File Upload Window
                AutomationElement desktopObject = AutomationElement.RootElement;
                PropertyCondition popUpWindowNameCondition = new PropertyCondition(AutomationElement.NameProperty, title.Trim());
                AutomationElement popUpWindow = desktopObject.FindFirst(TreeScope.Subtree, popUpWindowNameCondition);
                if (popUpWindow == null) throw new Exception("File Upload dialog window not found");


                //  FileTextBox
                PropertyCondition fileTextBoxCondition = new PropertyCondition(AutomationElement.NameProperty, fileTextBoxName.Trim());
                AutomationElement fileTextBox = popUpWindow.FindFirst(TreeScope.Subtree,
                    new AndCondition(fileTextBoxCondition,
                    new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit)));
                if (fileTextBox == null) throw new Exception("File textbox not found");

                try
                {
                    SetForegroundWindow(popUpWindow, 0);
                }
                catch (Exception ex)
                {

                }
                Thread.Sleep(2000);

                try
                {
                    fileTextBox.SetFocus();
                }
                catch (Exception ex)
                {

                }

                ValuePattern etb = fileTextBox.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
                etb.SetValue(extractedFields["UploadFilePath"].ToString());

                Thread.Sleep(2000);

                PropertyCondition buttonCondition = new PropertyCondition(AutomationElement.NameProperty, "Open");
                AutomationElement buttonElement = popUpWindow.FindFirst(TreeScope.Descendants, buttonCondition);
                if (buttonElement == null) throw new Exception("Button not found");
                try
                {
                    AutomationElement button = buttonElement;
                    InvokePattern buttonPattern = button.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
                    buttonPattern.Invoke();

                }
                catch (Exception ex)
                {
                    SendKeys.SendWait("{Enter}");
                }

   static int RETRY_LIMIT = 3;
        public static bool SetForegroundWindow(AutomationElement elm, uint retries, int time = 2000)
        {
            try
            {
                if (retries < RETRY_LIMIT)
                {
                    // Using Win32 to set foreground window because
                    // AutomationElement.SetFocus() is unreliable

                    // Get handle to the element
                    IntPtr other = FindWindow(null, elm.Current.Name);

                    // Get the Process ID for the element we are trying to
                    // set as the foreground element
                    int other_id = GetWindowThreadProcessId(
                        other, IntPtr.Zero);

                    // Get the Process ID for the current process
                    int this_id = GetWindowThreadProcessId(
                        Process.GetCurrentProcess().Handle, IntPtr.Zero);

                    // Attach the current process's input to that of the 
                    // given element. We have to do this otherwise the
                    // WM_SETFOCUS message will be ignored by the element.
                    bool success =
                        AttachThreadInput(this_id, other_id, true);

                    // Make the Win32 call
                    IntPtr previous = SetForegroundWindow(other);

                    if (IntPtr.Zero.Equals(previous))
                    {
                        // Trigger re-try
                        throw new Exception(
                            "SetForegroundWindow failed");
                    }
                    return true;
                }

                // Exceeded retry limit, failed!
                return false;
            }
            catch
            {
                retries++;
                Thread.Sleep(time);
                return SetForegroundWindow(elm, retries);
            }
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern bool AttachThreadInput(int idAttach, int idAttachTo, bool fAttach);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern int GetWindowThreadProcessId(IntPtr hWnd, IntPtr lpdwProcessId);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SetForegroundWindow(IntPtr hWnd);

使用上述蝙蝠与RDP断开连接后,代码可以正常工作。但是问题大约在12个小时后开始。日志文件中没有记录错误。 (我已从下面的代码中删除了日志,以使其保持较小状态)。该代码找到打开的对话框,甚至是文件文本框。日志说它已经输入了文件路径。甚至单击打开按钮。但是实际上没有选择该文件。该网站在按上载按钮时会发出警报,提示您选择文件。仅当我重新连接到RDP并使用上面的蝙蝠与RDP断开连接时,此问题才能解决。我想知道代码是否有可能在每12小时不重新连接到RDP的情况下工作?

0 个答案:

没有答案