2008-09-29 18 views
19

He estado buscando, y no he encontrado cómo lo haría desde C#.C# - Envío de mensajes a Google Chrome desde la aplicación C#

yo quería hacer, así que podría decirle a Google Chrome para ir Adelante, Volver, Abrir una nueva pestaña, Cerrar pestaña, abierto una nueva ventana, y cerrar ventana de mi Aplicación C#.

he hecho algo similar con el uso de WinAmp

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

y algunos otros. Pero no sé qué mensaje enviar o cómo encontrar a qué ventana se lo debe pasar, ni nada.

Entonces, ¿alguien podría mostrarme cómo enviaría esos 6 comandos a Chrome desde C#? gracias

EDIT: Ok, me votaron a la baja, por lo que tal vez no fui lo suficientemente claro, o la gente está asumiendo que no intenté resolver esto por mi cuenta.

En primer lugar, no soy muy bueno con todo el material de DllImport. Todavía estoy aprendiendo cómo funciona todo.

He encontrado cómo hacer la misma idea en winamp hace unos años, y estaba mirando mi código. Lo hice para poder omitir una canción, regresar, reproducir, pausar y detener el winamp de mi código C#. Comencé importando:

[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); 

Luego, el código que encontré utilizar usó estas constantes para los mensajes que envío.

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; 

que tendría la hwnd (el programa para enviar el mensaje a) por:

IntPtr hwnd = FindWindow(m_windowName, null); 

entonces me gustaría enviar un mensaje a ese programa:

SendMessageA(hwnd, WM_COMMAND, WA_STOP, WA_NOTHING); 

I Supongo que haría algo muy similar a esto para Google Chrome. pero no sé cuáles deberían ser algunos de esos valores, busqué en Google tratando de encontrar la respuesta, pero no pude, y por eso pregunté aquí. Así que mi pregunta es ¿cómo puedo obtener los valores para:

m_windowName y WM_COMMAND

y luego, los valores para los diferentes comandos, hacia adelante, volver, nueva pestaña, cerrar pestaña, nueva ventana, cerrar ventana?

Respuesta

9

comenzar su investigación en http://dev.chromium.org/developers


EDITAR: Envío de un mensaje a una ventana es sólo la mitad del trabajo. La ventana tiene que responder a ese mensaje y actuar en consecuencia. Si esa ventana no conoce un mensaje o no le importa en absoluto, no tiene posibilidad de controlarlo enviando mensajes a la ventana.

Está viendo un detalle de implementación sobre cómo controló Winamp a distancia. Enviar mensajes es solo una forma de hacerlo y es la forma en que los desarrolladores de Winamp eligieron. Los mensajes que está utilizando son mensajes definidos por el usuario que tienen un significado específico solo en Winamp.

Lo que tienes que hacer en el primer paso es averiguar si Chromium admite algún tipo de control remoto y cuáles son esos mecanismos.

+0

Estoy mirando, y no veo nada que me ayude a lograr lo que estoy tratando de hacer. No quiero recompilar Chrome ni nada. Quiero poder enviarle a Chrome un pequeño mensaje que diga "volver" o lo que sea. No quiero cambiar Chrome en absoluto. Hazlo todo desde C# – Joel

7

Puede obtener el nombre de la ventana fácilmente usando Visual Studio's Spy ++ y presionando CTRL + F, y luego encontrando chrome. Lo intenté y obtuve

"Chrome_VistaFrame" para la ventana de salida. La ventana actual con la página web es "Chrome_RenderWidgetHostHWND".

Por lo que respecta a WM_COMMAND, tendrá que experimentar. Obviamente, desea enviar clics de botón (WM_MOUSEDOWN de la parte superior de mi cabeza). Como los botones Atrás y Atrás no son sus propias ventanas, deberá averiguar cómo hacer esto simulando un clic del mouse en una determinada posición x, y para que Chrome sepa lo que está haciendo. O puede enviar el atajo de teclado equivalente para atrás/adelante y así sucesivamente.

Un ejemplo que escribí hace un tiempo lo hace con trillian y winamp: sending messages to windows via c# and winapi

También hay herramientas que hay a lo macro a cabo este tipo de cosas ya, usando un lenguaje de script - autoit es que he utilizado: autoit.com

+0

Así que he estado jugando con esto durante una hora o dos. Quiero enviar los atajos de teclado. En este momento estoy tratando de averiguar cómo enviar a Chrome el mensaje para WM_KEYDOWN y WM_KEYUP para la clave VK_BROWSER_BACK. Pero no puedo descifrar los valores int para ellos. – Joel

4

Ok, esto es lo que tengo hasta ahora ... la clase I sé lo que tengo que hacer, pero es sólo una cuestión de hacer ahora ...

aquí está la ventana de Spy ++, me bloqueado en el Chrome_RenderWidgetHostHWND e hizo clic en el botón Atrás en mi teclado. Aquí es lo que tengo: alt text

Así que aquí es mi hipótesis, y he estado jugando con esto para siempre ahora, simplemente no puedo averiguar los valores .

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

Ahora, sólo que no sé lo que debería hacer que los WM_KEYDOWN/UP valores o los valores VK_BROWSER_BACK/adelante ... yo probamos este:

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

Los últimos dos valores I obtuve de la imagen que acabo de mostrar, los ScanCodes para esas dos claves. No sé si lo hice bien sin embargo. Los dos valores anteriores que obtuve después de buscar en google el valor WM_KEYDOWN, y alguien usó & H100 y & H101 para los dos valores. He intentado varias otras ideas aleatorias que he visto flotando. Simplemente no puedo resolver esto.

Ah, y aquí está el método SendMessage

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

Este es un gran sitio para las constantes de interoperabilidad:

pinvoke

Otra forma de encontrar los valores es buscar koders.com, usando C# como idioma, para WM_KEYDOWN o la constante que busca:

Koders.com search

& Los valores H parecen de VB (6). PInvoke y Koders tanto devuelven resultados para 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; 

(Es curioso cómo muchos DEFINCIONES equivocadas de las constantes VK están flotando alrededor, teniendo en cuenta VK_ * son de 1 byte 0-255 valores, y la gente ha hecho uints).

Parece ligeramente diferente de sus consts. Creo que la función que buscas es SendInput (pero no lo he probado) ya que es una clave virtual.

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

Explicación sobre los parámetros:

Parámetros

  • nInputs- número de estructuras de la matriz pInputs.
  • pInputs - Puntero a una matriz de estructuras de ENTRADA. Cada estructura representa un evento que se insertará en la secuencia de entrada del teclado o del mouse.
  • cbSize: especifica el tamaño, en bytes, de una estructura de ENTRADA. Si cbSize no tiene el tamaño de una estructura INPUT, la función falla.

Esto necesita un tipo 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; 
} 

Y por último una muestra, que no he probado si funciona:

/* 
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])); 
} 

también tendrá que enfocar el cromo ventana usando SetForegroundWindow

Cuestiones relacionadas