C# – отправка сообщений в Google Chrome из приложения C#

StackOverflow https://stackoverflow.com/questions/147929

  •  02-07-2019
  •  | 
  •  

Вопрос

Я искал и не нашел, как это сделать на С#.

Я хотел сделать так, чтобы можно было попросить Google Chrome уйти. Вперед, Назад, Открыть новую вкладку, Закрыть вкладку, Открыть новое окно, и Закрой окно из моего приложения C#.

Я сделал нечто подобное с WinAmp, используя

[DllImport("user32", EntryPoint = "SendMessageA")]
private static extern int SendMessage(int Hwnd, int wMsg, int wParam, int lParam);

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

Так может ли кто-нибудь показать мне, как отправить эти 6 команд в Chrome с C#?Спасибо

РЕДАКТИРОВАТЬ:Хорошо, меня отвергли, так что, возможно, я недостаточно ясно выразился, или люди полагают, что я не пытался разобраться в этом самостоятельно.

Во-первых, я не очень хорошо разбираюсь во всей этой штуке DllImport.Я все еще учусь, как все это работает.

Несколько лет назад я нашел, как реализовать ту же идею в Winamp, и просматривал свой код.Я сделал это так, чтобы можно было пропустить песню, вернуться назад, воспроизвести, поставить на паузу и остановить Winamp из моего кода C#.Я начал с импорта:

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr FindWindow([MarshalAs(UnmanagedType.LPTStr)] string lpClassName, [MarshalAs(UnmanagedType.LPTStr)] string lpWindowName);
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern int SendMessageA(IntPtr hwnd, int wMsg, int wParam, uint lParam);
    [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    public static extern int GetWindowText(IntPtr hwnd, string lpString, int cch);
    [DllImport("user32", EntryPoint = "FindWindowExA")]
    private static extern int FindWindowEx(int hWnd1, int hWnd2, string lpsz1, string lpsz2);
    [DllImport("user32", EntryPoint = "SendMessageA")]
    private static extern int SendMessage(int Hwnd, int wMsg, int wParam, int lParam);

Затем код, который я нашел для этого, использовал эти константы для отправляемых мной сообщений.

    const int WM_COMMAND = 0x111;
    const int WA_NOTHING = 0;
    const int WA_PREVTRACK = 40044;
    const int WA_PLAY = 40045;
    const int WA_PAUSE = 40046;
    const int WA_STOP = 40047;
    const int WA_NEXTTRACK = 40048;
    const int WA_VOLUMEUP = 40058;
    const int WA_VOLUMEDOWN = 40059;
    const int WINAMP_FFWD5S = 40060;
    const int WINAMP_REW5S = 40061;

я бы получил хунд (программа для отправки сообщения) с помощью:

IntPtr hwnd = FindWindow(m_windowName, null);

тогда я бы отправил сообщение этой программе:

SendMessageA(hwnd, WM_COMMAND, WA_STOP, WA_NOTHING);

Я предполагаю, что сделал бы что-то очень похожее для Google Chrome.но я не знаю, какими должны быть некоторые из этих значений, и я гуглил, пытаясь найти ответ, но не смог, поэтому и спросил здесь.Итак, мой вопрос: как мне получить значения для:

m_windowName и WM_COMMAND

а затем значения для разных команд, вперед, назад, новая вкладка, Закрыть вкладку, новое окно, закрой окно?

Это было полезно?

Решение

Начните свое исследование на http://dev.chromium.org/developers


РЕДАКТИРОВАТЬ:Отправка сообщения в окно — это только половина дела.Окно должно отреагировать на это сообщение и действовать соответствующим образом.Если это окно не знает о сообщении или его вообще не волнует, у вас нет возможности контролировать его, отправляя оконные сообщения.

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

Что вам нужно сделать на первом этапе, это выяснить если Chromium поддерживает своего рода удаленное управление и его механизмы.

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

Вы можете легко получить имя окна, используя Spy++ Visual Studio и нажав CTRL+F, а затем найдя chrome.Я попробовал и получил

«Chrome_VistaFrame» для выходного окна.Фактическое окно с веб-страницей — «Chrome_RenderWidgetHostHWND».

Что касается WM_COMMAND — вам придется поэкспериментировать.Вы, очевидно, захотите отправлять нажатия кнопок (WM_MOUSEDOWN сверху у меня в голове).Поскольку кнопки «Назад» и «Вперед» не являются отдельными окнами, вам нужно будет выяснить, как это сделать, имитируя щелчок мыши в определенной позиции x, y, чтобы Chrome знал, что вы делаете.Или вы можете отправить эквивалент сочетания клавиш для перемещения вперед/назад и т. д.

Пример, который я написал некоторое время назад, делает это с trillian и winamp: отправка сообщений в Windows через C# и Winapi

Также существуют инструменты для макросов такого рода с использованием языка сценариев - я использовал autoit: autoit.com

Хорошо, вот что у меня пока есть...Я вроде знаю, что мне нужно делать, но это просто вопрос сделать это сейчас...

Вот окно из Spy++, я зафиксировал Chrome_RenderWidgetHostHWND и нажал кнопку «Назад» на клавиатуре.Вот что я получил:alt text

Итак, вот мои предположения, и я играю с этим вечно, я просто не могу понять, ценности.

IntPtr hWnd = FindWindow("Chrome_RenderWidgetHostHWND", null);
SendMessage(hWnd, WM_KEYDOWN, VK_BROWSER_BACK, 0);
SendMessage(hWnd, WM_KEYUP,   VK_BROWSER_BACK, 0);

Теперь я просто не знаю, что мне следует сделать: значения WM_KEYDOWN/UP или значения VK_BROWSER_BACK/FORWARD...Я попробовал это:

const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;
const int VK_BROWSER_BACK = 0x6A;
const int VK_BROWSER_FORWARD = 0x69;

Последние два значения я получил из изображения, которое только что показал, — это ScanCodes для этих двух ключей.Хотя я не знаю, правильно ли я это сделал.Первые два значения я получил после поиска в Google значения WM_KEYDOWN, и кто-то использовал &H100 и &H101 для этих двух значений.Я попробовал несколько других случайных идей, которые, как я видел, витали в воздухе.Я просто не могу этого понять.

О, и вот метод SendMessage

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, uint lParam);

Это отличный сайт для констант взаимодействия:

контактный вызов

Другой способ найти значения — выполнить поиск на сайте koders.com, используя в качестве языка C#, WM_KEYDOWN или искомую константу:

Поиск на Koders.com

Значения &H выглядят так, как будто они взяты из VB(6).pinvoke и koders возвращают результаты для VK_BROWSER_FORWARD,

private const UInt32 WM_KEYDOWN        = 0x0100;
private const UInt32 WM_KEYUP          = 0x0101;

public const ushort VK_BROWSER_BACK = 0xA6;
public const ushort VK_BROWSER_FORWARD = 0xA7;
public const ushort VK_BROWSER_REFRESH = 0xA8;
public const ushort VK_BROWSER_STOP = 0xA9;
public const ushort VK_BROWSER_SEARCH = 0xAA;
public const ushort VK_BROWSER_FAVORITES = 0xAB;
public const ushort VK_BROWSER_HOME = 0xAC;

(Забавно, сколько неправильных определений констант VK встречается, учитывая, что VK_* — это 1-байтовые значения от 0 до 255, а люди сделали их uints).

Выглядит немного иначе, чем ваши константы.Я думаю, что вам нужна функция SendInput (но я ее не пробовал), поскольку это виртуальный ключ.

[DllImport("User32.dll")]
private static extern uint SendInput(uint numberOfInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] KEYBOARD_INPUT[] input, int structSize);

Пояснения к параметрам:

Параметры

  • nInputs — количество структур в массиве pInputs.
  • pInputs — указатель на массив структур INPUT.Каждая структура представляет событие, которое необходимо вставить в поток ввода с клавиатуры или мыши.
  • cbSize — определяет размер структуры INPUT в байтах.Если cbSize не соответствует размеру структуры INPUT, функция завершается с ошибкой.

Для этого нужен тип KEYBOARD_INPUT:

[StructLayout(LayoutKind.Sequential)] 
public struct KEYBOARD_INPUT
{ 
    public uint type; 
    public ushort vk; 
    public ushort scanCode; 
    public uint flags; 
    public uint time; 
    public uint extrainfo; 
    public uint padding1; 
    public uint padding2; 
}

И, наконец, образец, который я не проверял, работает ли он:

/*
typedef struct tagKEYBDINPUT {
    WORD wVk;
    WORD wScan;
    DWORD dwFlags;
    DWORD time;
    ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT;
*/
public static void sendKey(int scanCode, bool press)
{
        KEYBOARD_INPUT[] input = new KEYBOARD_INPUT[1];
        input[0] = new KEYBOARD_INPUT();
        input[0].type = INPUT_KEYBOARD;
        input[0].vk = VK_BROWSER_BACK;

    uint result = SendInput(1, input, Marshal.SizeOf(input[0]));
}

Также вам нужно будет сфокусировать окно Chrome, используя УстановитьПередний ПланОкно

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top