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

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

Вы пробовали перемещать мышь каждую минуту?

Miłosz Wierzbicki 22.10.2018 18:17

Вроде программно ?? Не могли бы вы привести пример с .net?

Amey Banaye 23.10.2018 19:04

Попробуйте MouseHandler из этой библиотеки nuget: github.com/quellatalo/TheHands

Miłosz Wierzbicki 24.10.2018 11:09
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
351
0

Другие вопросы по теме