Проблема автоматизации пользовательского интерфейса Windows и подключения к удаленному рабочему столу - PullRequest
0 голосов
/ 06 сентября 2018

Возникла проблема при автоматизации процесса загрузки файлов через браузер 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, используя вышеупомянутую bat. Но проблема начинается после 12 часов. В файле журнала нет ошибок. (Я удалил журналы из кода ниже для того, чтобы он был маленьким). Код находит открытое диалоговое окно и даже текстовое поле файла. В журнале говорится, что он ввел путь к файлу. И даже кнопка открытия нажата. Но на самом деле файл не выбран. На веб-сайте выдается предупреждение о выборе файла при нажатии кнопки загрузки. Проблема решается только тогда, когда я повторно подключаюсь к RDP и использую вышеупомянутую летучую мышь для отключения от RDP. Я хочу знать, есть ли возможность для кода работать без повторного подключения к RDP через каждые 12 часов?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...