C # - отправка сообщений в Google Chrome из приложения C # - PullRequest
19 голосов
/ 29 сентября 2008

Я искал вокруг, и я не нашел, как я мог бы сделать это из C #.

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

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

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

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

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

EDIT: Хорошо, за меня проголосовали, так что, возможно, я не был достаточно ясен, или люди предполагают, что я не пытался выяснить это самостоятельно.

Во-первых, я не очень хорош со всем, что связано с 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;

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

IntPtr hwnd = FindWindow(m_windowName, null);

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

SendMessageA(hwnd, WM_COMMAND, WA_STOP, WA_NOTHING);

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

m_windowName и WM_COMMAND

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

Ответы [ 4 ]

9 голосов
/ 29 сентября 2008

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


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

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

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

7 голосов
/ 29 сентября 2008

Вы можете легко получить имя окна, используя 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

4 голосов
/ 30 сентября 2008

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

PInvoke

Еще один способ поиска значений - поиск на 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, и люди сделали их уинтами).

Выглядит немного иначе, чем твои супруги. Я думаю, что вам нужна функция 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, используя SetForegroundWindow

4 голосов
/ 29 сентября 2008

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

Вот окно из 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...