С# - отправка сообщений в Google Chrome из приложения С#
Я искал вокруг, и я не нашел, как это сделать с С#.
Я хотел сделать так, чтобы Google Chrome мог перейти Вперед, Назад, Открыть новую вкладку, Закрыть Tab, Открыть новое окно и закрыть окно из моего приложения С#.
Я сделал что-то подобное с WinAmp, используя
[DllImport("user32", EntryPoint = "SendMessageA")]
private static extern int SendMessage(int Hwnd, int wMsg, int wParam, int lParam);
и несколько других. Но я не знаю, какое сообщение отправить или как найти, в каком окне передать это, или что-нибудь еще.
Так может кто-нибудь показать мне, как я отправлю эти 6 команд в Chrome с С#? спасибо
EDIT:
Хорошо, меня проголосовали, так что, возможно, я не был достаточно ясен, или люди предполагают, что я не пытался это понять сам по себе.
Во-первых, я не очень хорош со всем материалом DllImport. Я все еще изучаю, как все это работает.
Я нашел, как сделать ту же идею в winamp несколько лет назад, и я смотрел на свой код. Я сделал это, чтобы я мог пропустить песню, вернуться, сыграть, приостановить и остановить winamp из моего кода на С#. Я начал с импорта:
[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
а затем значения для разных команд, переслать, назад, новую вкладку, закрыть вкладку, новое окно, закрыть окно?
Ответы
Ответ 1
Начните свое исследование http://dev.chromium.org/developers
EDIT. Отправка сообщения в окно составляет только половину работы. Окно должно ответить на это сообщение и действовать соответствующим образом. Если это окно не знает о сообщении или вообще не заботится, у вас нет возможности контролировать его, отправив сообщения в окне.
Вы изучаете детальную информацию о том, как вы дистанционно управляете Winamp. Отправка сообщений - это всего лишь один способ сделать это, и это то, что выбрали разработчики Winamp. Те сообщения, которые вы используете, - это пользовательские сообщения, которые имеют конкретное значение только для Winamp.
Что вам нужно сделать на первом шаге, так это выяснить, поддерживает ли Chromium какой-то дистанционный контроль и какие существуют эти механизмы.
Ответ 2
Вы можете легко получить имя окна с помощью Visual Studio Spy ++ и нажав CTRL + F, а затем найти хром. Я попробовал и получил
"Chrome_VistaFrame" для выходного окна. Фактическое окно с веб-страницей - "Chrome_RenderWidgetHostHWND".
Что касается WM_COMMAND, вам нужно поэкспериментировать. Вы, очевидно, захотите отправить клики по кнопкам (WM_MOUSEDOWN сверху с моей головы). Поскольку спина, кнопки вперед не являются их собственными окнами, вам нужно выяснить, как это сделать, имитируя щелчок мыши в определенной позиции x, y, поэтому хром знает, что вы делаете. Или вы можете отправить эквивалент ярлыка клавиатуры для обратной/прямой и т.д.
Пример, который я написал некоторое время назад, делает это с помощью trillian и winamp: отправка сообщений в окна через С# и winapi
Там также есть инструменты для макросов такого рода, используя язык сценариев - autoit - это тот, который я использовал: autoit.com
Ответ 3
Хорошо, вот что у меня до сих пор... Я как бы знаю, что мне нужно делать, но это просто вопрос сейчас...
Здесь окно из 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);
Ответ 4
Это отличный сайт для констант взаимодействия:
pinvoke
Другим способом поиска значений является поиск koders.com с использованием С# в качестве языка для 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, используя SetForegroundWindow