Как из 1С получить доступ к окну сторонней программы и передать в него текст?

Программист IT и автоматизация бизнеса
← На главную

В процессе интеграции 1С с внешними системами разработчики часто сталкиваются с ситуацией, когда у стороннего приложения полностью отсутствует API (COM, веб-сервисы, HTTP-сервисы или direct-подключение к базе данных). Единственный способ передать данные в такую программу — это сымитировать действия пользователя: открыть окно, сделать его активным, вставить текст в нужное поле ввода и нажать клавишу Enter.

В рамках этой статьи мы подробно разберем несколько эффективных способов решения этой задачи: от простых встроенных механизмов Windows до профессиональных инструментов автоматизации интерфейсов.

Способ 1. Использование встроенного метода AppActivate в WScript.Shell

Самый быстрый и доступный способ, который не требует скачивания и установки стороннего программного обеспечения, — это использование стандартного системного объекта Windows WScript.Shell. У этого объекта есть полезный метод AppActivate, который умеет находить окно по его заголовку и выводить его на передний план.

Рассмотрим по шагам, как реализовать этот алгоритм на встроенном языке 1С:


// Создаем COM-объект для работы со сценариями Windows
Shell = Новый COMОбъект("WScript.Shell");

// Пробуем активировать окно. В параметре указываем точный заголовок или его начало
Если Shell.AppActivate("Калькулятор") Тогда
    
    // Делаем небольшую паузу, чтобы операционная система успела переключить фокус
    Предупреждение("Окно успешно найдено! Нажмите ОК для отправки текста.", 1);
    
    // Передаем строку символов в активное поле ввода
    Shell.SendKeys("555+444");
    
    // Эмулируем нажатие клавиши Enter (в SendKeys она обозначается как {ENTER} или знак ~)
    Shell.SendKeys("{ENTER}");
Иначе
    Сообщить("Не удалось найти окно с указанным заголовком.");
КонецЕсли;

Преимущества метода: работает "из коробки" на любом компьютере под управлением ОС Windows, не требует прав администратора и регистрации внешних библиотек.

Недостатки метода: если в момент отправки текста пользователь случайно кликнет мышкой по другому окну, фокус ввода собьется, и данные напечатаются не там, где планировалось. Кроме того, метод чувствителен к текущей раскладке клавиатуры.

Способ 2. Использование скриптов AutoIt, скомпилированных в EXE-файл

Это классическое и наиболее надежное решение, которое активно обсуждалось участниками форума. Утилита AutoIt специально разработана для автоматизации интерфейса Windows. Она умеет находить не просто окно, но и конкретные элементы внутри него (поля ввода, кнопки, чекбоксы) по их системным идентификаторам.

Чтобы не устанавливать саму программу AutoIt на рабочие компьютеры пользователей, мы можем написать скрипт один раз, скомпилировать его в автономный файл .exe и запускать его из 1С.

Разберем процесс реализации по шагам:

  1. Скачиваем портативную версию AutoIt с официального сайта.
  2. Создаем текстовый файл скрипта с расширением .au3 (например, send_data.au3).
  3. Записываем в него следующий код, который активирует окно и вносит текст в конкретное поле ввода:

; Ожидаем появления окна программы в течение 10 секунд
WinWait("Заголовок целевой программы", "", 10)

; Активируем окно
WinActivate("Заголовок целевой программы")

; Ждем, пока окно станет полностью активным
WinWaitActive("Заголовок целевой программы")

; Записываем текст в нужное поле. "Edit1" - это класс поля ввода (его можно узнать утилитой Active Window Info)
ControlSetText("Заголовок целевой программы", "", "Edit1", "Привет из 1С!")

; Эмулируем нажатие клавиши Enter в этом поле
ControlSend("Заголовок целевой программы", "", "Edit1", "{ENTER}")
  1. Компилируем скрипт в исполняемый файл. Для этого открываем AutoIt Script Editor, загружаем наш файл скрипта и нажимаем клавишу F7 (или выбираем пункт меню "Compile"). На выходе получаем готовый файл send_data.exe.
  2. В коде 1С запускаем этот файл, передавая нужные параметры через командную строку:

// Запускаем скомпилированный скрипт из 1С
ИмяФайлаСкрипта = "C:\Automation\send_data.exe";
ЗапуститьПриложение(ИмяФайлаСкрипта, , Истина);

Использование ControlSetText и ControlSend в AutoIt гарантирует, что данные будут доставлены в конкретное поле ввода, даже если пользователь переключит фокус на другое приложение во время работы скрипта.

Способ 3. Запуск команд через PowerShell (без внешних файлов)

Если нам необходимо получить стабильность, сопоставимую с AutoIt, но при этом мы принципиально не хотим использовать внешние файлы .exe, отличным выходом будет использование встроенной оболочки PowerShell. Из нее мы можем напрямую вызывать классы платформы .NET Framework.

Проанализируем пример кода на стороне 1С, который выполняет эту операцию в фоне:


// Формируем команду PowerShell, которая активирует окно и отправляет нажатия клавиш
КомандаPS = "powershell -Command ""Add-Type -AssemblyName Microsoft.VisualBasic, System.Windows.Forms; " +
            "[Microsoft.VisualBasic.Interaction]::AppActivate('Имя сторонней программы'); " +
            "[System.Windows.Forms.SendKeys]::SendWait('ПередаваемыйТекст{ENTER}')""";

// Выполняем команду в скрытом режиме (параметр ожидания завершения установлен в Истина)
ЗапуститьПриложение(КомандаPS, , Истина);

Этот способ работает точнее, чем обычный WScript.Shell, так как методы .NET осуществляют более глубокую интеграцию с подсистемой управления окнами операционной системы.

Способ 4. Профессиональный подход через WinAPI и DynamicWrapperX

Самым надежным способом управления чужими окнами является прямая отправка сообщений операционной системы Windows через функции прикладного интерфейса (WinAPI): FindWindow, FindWindowEx и SendMessage.

Поскольку встроенный язык 1С напрямую не работает с WinAPI, используется легкая внешняя компонента DynamicWrapperX, которую нужно предварительно зарегистрировать в системе.

Давайте выясним принцип работы данного метода:

  1. Функция FindWindow находит дескриптор (HWND) главного окна стороннего приложения по его классу или точному заголовку.
  2. Функция FindWindowEx производит поиск внутри главного окна и находит дескриптор конкретного дочернего элемента — поля ввода.
  3. Функция SendMessage посылает системное сообщение WM_SETTEXT непосредственно в найденный элемент управления.

Главное преимущество этого метода: текст вставляется мгновенно на системном уровне. Окно целевой программы может быть свернуто в трей, находиться на заднем плане или быть полностью перекрыто другими окнами — передача данных все равно пройдет успешно, без активации интерфейса и мерцания экрана.

Резюме и рекомендации

При выборе подходящего метода автоматизации рекомендуем придерживаться следующих правил:

← На главную