Как управлять другой программой

Понимаю что это все можно сделать через WinApi но не понимаю где взять описания функций (желательно на русском) и как их встраивать в код C#.
Например, как это делалось в VB 6.0 помню.

Отслеживать
397 2 2 золотых знака 10 10 серебряных знаков 39 39 бронзовых знаков
задан 4 апр 2016 в 10:54
265 2 2 серебряных знака 12 12 бронзовых знаков
Описание функций WinAPI ищите в MSDN
4 апр 2016 в 10:58

25 июл 2020 в 11:44

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Для вашей задачи вполне подойдёт стандартный майкрософтовский UI Automation. Вот пример без P/Invoke:

var notepadProcess = Process.GetProcessesByName(«Notepad»).FirstOrDefault(); var window = AutomationElement.FromHandle(notepadProcess.MainWindowHandle); var transformPattern = (TransformPattern)window.GetCurrentPattern(TransformPattern.Pattern); transformPattern.Resize(300, 300);

(изменяет размер окна notepad.exe на 300х300).

Не забудьте подключить сборки UIAutomationClient и UIAutomationTypes и добавить контроль ошибок.

Уроки WinApi C++ | Работа с окнами виндовс | HWND на примерах

В MSDN есть документация об остальной функциональности UI Automation. Например, как активировать контрол (нажать на кнопку, выбрать пункт меню и т. п.).

Список всех подокон и их доступных свойств легко подсмотреть при помощи утилиты Inspect.exe из Windows SDK.

После небольшого упражнения в гуглопоиске на стэковерфлоу, вот более серьёзный пример:

В коде используется следующий простой хелпер:

static class AutomationHelpers < static public T GetPattern(this AutomationElement element) where T : BasePattern < var pattern = (AutomationPattern)typeof(T).GetField(«Pattern»).GetValue(null); return (T)element.GetCurrentPattern(pattern); >static public AutomationElement FirstChildByType( this AutomationElement element, ControlType ct) < return element.FindFirst( TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ct)); >static public AutomationElement FirstDescendantByTypeAndName( this AutomationElement element, ControlType ct, string name) < return element.FindFirst( TreeScope.Descendants, new AndCondition( new PropertyCondition(AutomationElement.ControlTypeProperty, ct), new PropertyCondition(AutomationElement.NameProperty, name))); >static public AutomationElement FindWindowFrom(AutomationElement control) < var walker = TreeWalker.ControlViewWalker; while (control.Current.ControlType != ControlType.Window) control = walker.GetParent(control); return control; >>

VB.NET справится точно так же, функциональность UI Automation доступна в обоих языках.

Добавил паузы в секунду между действиями и адаптировал к русской системе (другие названия пунктов меню), результат:

Источник: ru.stackoverflow.com

Как управлять другим компьютером со своего или подключится к другому компьютеру

Как управлять другой программой

jetcar
Советую подождать местных спецов по WinAPI, они обычно быстро появляются на подобных темах )).

Добавлено:
Или вообще пойти смотреть топики по WinAPI. А на C# P/Invoke юзать для вызова нужных WinAPI-функций.

Цитата:

Ты можешь только мониторить интерфейс
Читайте также:
Убедитесь что программа epic установлена

но ведь можно найти адрес в памяти и за ним тогда следить если по другому ни как

Цитата:

хочешь сказать, что даже на сообщение немедленного завершения приложения оно будет ждать пока пользователь не активирует его?

Читай внимательно — я писал — Ты можешь только мониторить интерфейс. Функции завершения приложения — это интерфейс. Если не сработала то метод kill.

Цитата:

также как если мы пошлем из др. программы сообщение на ее hWnd.

У меня прога в систрее свёрнута и ловит просьбу показать текст ввиде баллончика, очень удобная штука так как отдельный процесс не задерживает отладчик. Но когда я писал компонент систрей, на нажатие мне приходилось сначала активировать аппликацию, потом покаывать главное окно потом делать RestoreTopMost. Подбирал последовательность чисто экспериментально. Если не выполнять точной последовательности то будет куча глюков. Например если не активировать аппликацию и делать показ окна, то компоненты не перерисовываются. И только стандартное меню перерисовывается если сделать Invalidate. Так что привыкай к мысли, что без грамотной последовательности сообщений огребёшь кучу глюков.

Цитата:

но ведь можно найти адрес в памяти и за ним тогда следить если по другому ни как

Это можно, хотя это трудно реализуется, но реализуемо. Я пользовался для этого JCL/JVCL. Пробовал попачить немного одну игрулю. Кстати различные Артмони так и делают. Сканят память на значение, потом когда значение меняется отбрасывают те участки в которых оно не изменилось.

ShIvADeSt
Давненько мы не болтали про AllocateHWnd и WndProc

Цитата:

это можно делать и со свернутой программой ИМХО, не тестил, но проблем не вижу

Ну может текст из TEdit (я про VCL) ты получишь, но изменить его не сможешь, сам же знаешь, что то что ты на винде нарисовал физически VCL запросто проигнорирует, так как проверяет оно свойство Modified, и если не редактировали, то плевать что рисует винда. Так что судя по желаниям у человека их много, вот если бы он конкретно определился, то можно было бы попытаться ему помочь.

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

Читайте также:
Как установить программу на компьютер driverpack

Цитата:

На свернутом не проверял — проверю.

Ну тольк представь нормальную программу. Нажимаем меню — вылазит диалоговое модальное окно свойств объекта. Мы в этом окне с помощью программы меняем цифирьку и нажимаем OK. Команду меню послать — ноль проблемм, менять цифирку — ноль проблемм, нажать OK — ноль проблемм. А теперь представим свёрнутое состояние. Прилетела команда и программа начинает рисовать модальное окно в свёрнутой апликации. Потом вдруг OK не прилетело, а в программе начался цикл. Пользователь жмёт пимпу, а прога не разворачивается, так как у окна был статус — критичное (это когда программу не свернуть пока нужную пимпу не ткнёшь). Так вот прога сдохла, а юзер даже не видел по что она здохла. Так я не припомню, чтобы диалоговые модальные окна могли выпадать в свёрнутой проге.

где посмотреть как поискать поправильнее?

Цитата:

а нету чтоли места где почитать о SendMessage можно?

Начинать следует с MSDN.

Цитата:

кстати как получить handle запущeнной программы System.Diagnostics.Process.Start(«notepad.exe»);
там можно узнать handle, но он какой-то не такой как GetForegroundWindow()
даёт

Что подразумевается под «handle запущeнной программы»? Хендл окна — это одно, хендл процесса — другое, хэндл потока — третье.
Опять же рекомендую почитать MSDN: Processes and Threads.

Источник: forum.ru-board.com

Как управлять другой программой

Под управлением сторонним приложением я подразумеваю некие действия своей программы, эмулирующие действия живого человека. Например, нажатия на кнопки в диалоговых окнах. Попробуем сделать это на примере лоадера для популярного файлового менеджера Total Commander. Кто пользуется им, тот знает, что единственное различие между полной и незарегистрированной версией в том, что триалка при запуске показывает наг-скрин с предложением купить программу или нажать для продолжения одну из трех кнопок с цифрами. Конечно, кнопку можно нажать самостоятельно, но можно доверить это лоадеру.


Наг-скрин Total Commander

Чтобы работать с содержимым окна, сперва надо узнать его хэндл. Проще всего воспользоваться функцией FindWindow, указав в качестве параметра наименование класса наг-скрина. Его можно посмотреть при помощи моей программы WinDowzer или любой другой аналогичной программы. Противное окно имеет название класса TNASTYNAGSCREEN, первый шаг сделан. Теперь нам надо узнать хэндл нужной кнопки, для этого нужно изучить все связи родительских и дочерних объектов окна.

Иерархический список хэндлов всех элементов нужного окна можно получить при помощи последовательного вызова функции FindWindowEx или же рекурсивного вызова функции EnumChildWindows. Вот что у меня получилось:

Читайте также:
Программа cropio что такое

TNASTYNAGSCREEN — Total Commander
TNotebook
TPage — NagPage
TPanel
TPanel — 3
TButton — 2
TButton — 3
TButton — 1
TButton — information
TPanel
TPanel — 3
TButton — 2
TButton — 3
TButton — 1
TButton — information
TPage — StartupPage
TPanel
TPanel
TPage — UserPage
TButton — Update Information
TPage — NagPage
TPanel
TPanel — 3
TButton — 2
TButton — 3
TButton — 1
TButton — information
TPanel
TPanel — 3
TButton — 2
TButton — 3
TButton — 1
TButton — information
TPage — StartupPage
TPanel
TPanel
TPage — UserPage
TButton — Update Information

В списке для удобства я записал название класса и текст дочерних окон. Казалось бы, в момент перебора надо просто «нажать» нужную кнопку. Но здесь не все так просто, так как каждый раз выбирается случайный номер кнопки, и если нажать неправильную, то Total Commander просто завершит работу. Значит нам еще надо узнать правильный номер кнопки, прежде чем «нажать» на нее.

Обратите внимание, что номер кнопки повторяется в форме несколько раз, и длина строки (то есть цифры) — всегда один символ. Облегчим себе задачу и рекурсивно переберем все дочерние элементы наг-скрина, а строку длиной один символ будем считать правильным номером.

Code (Assembler) : Убрать нумерациюВыделить код

Нужный нам номер в виде строки теперь записан в переменную button, причем именно так, как он написан на кнопке, то есть «. Нам осталось найти хэндл самой кнопки и «нажать» на нее. Воспользуемся точно таким же трюком, рекурсивно пройдемся по всем дочерним элементам и кликнем по всем найденным элементам, текст на которых совпадает с искомым номером кнопки.

Лирическое отступление. Наиболее правильная эмуляция клика на каком-либо элементе окна выглядит следующим образом:

Code (Assembler) : Убрать нумерациюВыделить код

  1. invoke SendMessage , [ hwnd ] , WM_SETFOCUS , NULL , NULL
  2. invoke SendMessage , [ hwnd ] , WM_LBUTTONDOWN , MK_LBUTTON , NULL
  3. invoke SendMessage , [ hwnd ] , WM_LBUTTONUP , MK_LBUTTON , NULL

Возвращаемся к перебору дочерних элементов наг-скрина.
Code (Assembler) : Убрать нумерациюВыделить код

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

Примеры программы с исходным текстом (FASM)

Источник: www.manhunter.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru