Управление курсором и окнами в C#


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



Итак, для начала, что с помощью кода ниже можно будет делать

А для чего все это было нужно?

Все просто. Был некий сайт, на который надо отправлять некий файл и забирать результат. Сайт с защитой, так что напрямую, без js (да даже и с js с безголовыми браузерами) не получалось ничего.

Реальный браузер + расширение – этот вариант решил задачу получения результата, но вот файл по-прежнему нельзя было отправить. Почему? У браузера существует некая «песочница», невозможность совершать некоторые действия скриптами JS. К таким действиям относится и заливка файла на сервер (или подстановка в input type file). Значит, придется задействовать еще одну программу. Использовать что-то типа Selenium тут заманчиво, но нерационально, все же проще добавить расширение для отслеживания изменений. Так что создадим просто проект в визуал студии для фреймворка например 4.7.2.

Подключаемые пространства имен

using System.Diagnostics;
using System.Runtime.InteropServices;
Запуск браузера хром сразу на нужной странице

Process.Start(@"chrome.exe", " https://upread.ru/blog/new");
Открыть проводник и сразу выделить в нем файл

Process PrFolder = new Process();
ProcessStartInfo psi = new ProcessStartInfo();
string file = @"C:\temp\upread.ru.png";
psi.CreateNoWindow = true;
psi.WindowStyle = ProcessWindowStyle.Normal;
psi.FileName = "explorer";
psi.Arguments = @"/n, /select, " + file;
PrFolder.StartInfo = psi;
PrFolder.Start();
Узнать дескриптор окна по названию окна

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

public static int FindWindow(string windowName, bool wait){
    int hWnd = (int)FindWindow(null, windowName);
    while (wait && hWnd == 0){
        System.Threading.Thread.Sleep(500);
        hWnd = (int)FindWindow(null, windowName);
    }

    return hWnd;
}
А вот так пользоваться. Обратите внимание, что заголовок окна проводника по умолчанию ставится открытая папка

int windww = FindWindow("temp", true);
Изменить позицию окна

[DllImport("user32.dll", SetLastError = true)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

const uint SWP_NOSIZE = 0x0001;
const uint SWP_NOZORDER = 0x0004;
Пример вызова:

SetWindowPos((IntPtr)windww, IntPtr.Zero, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
Установить позицию курсора по координатам

[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern bool SetCursorPos(int x, int y);

SetCursorPos(xStart, yStart);
Нажать левую кнопку мыши

[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

public const int MOUSEEVENTF_MOVE = 0x01;
public const int MOUSEEVENTF_LEFTDOWN = 0x02;
public const int MOUSEEVENTF_LEFTUP = 0x04;

mouse_event(MOUSEEVENTF_LEFTDOWN, xStart, yStart, 0, 0);
Переместить указатель мыши

mouse_event(MOUSEEVENTF_MOVE, xStart, 90, 0, 0);
Отпустить левую кнопку мыши

mouse_event(MOUSEEVENTF_LEFTUP, xEnd, yEnd, 0, 0);
Пауза

Интересный момент. Между действиями всегда делайте паузу, как бы шустер не был ваш компьютер! Если действия выполнять одно за другим, без паузы, то они просто не успевают отработать. Например, выделили файл, перенесли и тут же отпустили. Казалось бы, что такого. А вот не сработает такой код без паузы – просто пока не закончится выделение (или перемещение) – уже отработает отпускание нажатой клавиши мыши.

System.Threading.Thread.Sleep(1000);
Так что всегда, хотя бы доли секунды (в зависимости от машины) ставьте паузу. Секунда-две обычно хватает для любого компьютера.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, си шарп, автоматизация, курсор
Читайте также:




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Урок 22. Структуры C#
Урок 15. Исключения Java
Алгоритм быстрого объединения