Я пытаюсь написать веб-бота, который должен быть незамеченным, поэтому я не использую свойство InnerText
и вместо этого пытаюсь имитировать нажатия клавиш.Для этого мне нужно сфокусировать элемент <input>
, но фокус переключается на другое текстовое поле, а не сразу, даже после вызова element.Focus()
.
Я пробовал также использовать element.InvokeMember("click");
, но это не работаетлибо.
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
public const Int32 WM_CHAR = 0x0102;
public const Int32 WM_KEYDOWN = 0x0100;
public const Int32 WM_KEYUP = 0x0101;
public const Int32 VK_RETURN = 0x0D;
IntPtr BrowserHandle
{
get
{
var hwnd = _browser.Handle;
hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Shell Embedding", null);
hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Shell DocObject View", null);
hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Internet Explorer_Server", null);
return hwnd;
}
}
readonly Random _rnd = new Random();
private void Form1_Load(object sender, EventArgs e)
{
_browser.Navigate("https://...");
_browser.DocumentCompleted += _browser_DocumentCompleted;
}
private async void _browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (e.Url.AbsoluteUri != "https://...") return;
var inputs = _browser.Document.GetElementsByTagName("input");
{
var el = inputs.OfType<HtmlElement>().FirstOrDefault(x => x.GetAttribute("className").Contains("login"));
await SendTextAsync(el, "sdfoj30jfoigjdlsgfdgd");
}
}
async Task SendTextAsync(HtmlElement element, string text)
{
for (var i = 0; i < text.Length; i++, await Task.Delay(_rnd.Next(0, 500)))
{
if (_browser.Document.ActiveElement != element)
{
element.Focus(); // doesn't work
if (_browser.Document.ActiveElement != element)
{
element.InvokeMember("click"); // either
if (_browser.Document.ActiveElement != element)
{
element.Focus();
await Task.Delay(_rnd.Next(50, 250)); // anyway
}
}
}
var c = text[i];
SendCharacter(c, BrowserHandle);
}
}
static void SendCharacter(char character, IntPtr hWnd)
{
var key = new IntPtr(character);
SendMessage(hWnd, WM_KEYDOWN, key, IntPtr.Zero);
SendMessage(hWnd, WM_CHAR, key, IntPtr.Zero);
SendMessage(hWnd, WM_KEYUP, key, IntPtr.Zero);
}
}
Я ожидал, что этот код заполнит текстовое поле для входа в систему, но вместо этого он записывает туда несколько символов, а другие переходят в текстовое поле для пароля.