簡體   English   中英

C# - 從C#應用程序向Google Chrome發送消息

[英]C# - Sending messages to Google Chrome from C# application

我一直在尋找,我還沒有找到我將如何從C#中做到這一點。

我想要這樣做,所以我可以告訴谷歌Chrome從我的C#應用​​程序前進后退打開新標簽關閉標簽打開新窗口關閉窗口

我使用WinAmp做了類似的事情

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

還有一些其他人。 但我不知道要發送什么消息或者如何找到傳遞給它的窗口,或者其他什么。

那么有人可以告訴我如何從C#向Chrome發送這6個命令嗎? 謝謝

編輯:好的,我正在投票,所以也許我不夠清楚,或者人們假設我沒有試圖自己解決這個問題。

首先,我對整個DllImport的東西不太滿意。 我還在學習它是如何運作的。

幾年前我在winamp找到了如何做同樣的想法,我正在查看我的代碼。 我做了所以我可以跳過一首歌,回去,播放,暫停,並停止從我的C#代碼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做一些非常類似的事情。 但是我不知道這些價值觀應該是什么,我用Google搜索找到答案,但我不能,這就是我在這里問的原因。 所以我的問題是如何獲取以下值:

m_windowNameWM_COMMAND

然后,不同命令的值, 前進后退新選項卡關閉選項卡新窗口關閉窗口

http://dev.chromium.org/developers開始您的研究


編輯 :向窗口發送消息只是工作的一半。 窗口必須響應該消息並相應地采取行動。 如果該窗口不知道消息或根本不關心,則您無法通過發送窗口消息來控制它。

您正在查看有關如何遠程控制Winamp的實現細節。 發送消息只是實現它的一種方式,而這正是Winamp開發人員選擇的方式。 您正在使用的那些消息是用戶定義的消息, 僅對 Winamp具有特定含義。

你在第一步要做的是找出是否鉻支持某種遠程控制的以及這些機制。

您可以使用Visual Studio的Spy ++輕松獲取窗口名稱,然后按CTRL + F,然后找到chrome。 我試過了,得到了

用於out窗口的“Chrome_VistaFrame”。 帶有網頁的實際窗口是“Chrome_RenderWidgetHostHWND”。

就WM_COMMAND而言 - 你需要進行實驗。 你顯然想要發送按鈕點擊(我頭頂的WM_MOUSEDOWN)。 由於后退,前進按鈕不是他們自己的窗口,你需要弄清楚如何通過在某個x,y位置模擬鼠標點擊來實現這一點,以便Chrome知道你正在做什么。 或者您可以發送等效於后退/前進的鍵盤快捷鍵等。

我剛才寫的一個例子是trillian和winamp: 通過c#和winapi向windows發送消息

還有一些工具可以使用腳本語言來解決這種問題 - autoit是我使用過的: autoit.com

好的,這就是我到目前為止所得到的......我知道我需要做什么,但這只是現在做的事情......

這是Spy ++的窗口,我鎖定了Chrome_RenderWidgetHostHWND並單擊了鍵盤上的Back按鈕。 這是我得到的: 替代文字

所以這是我的假設,我現在一直在玩這個,我只是無法弄清楚價值觀

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。 我不知道我是否做得對。 我在搜索谷歌獲取WM_KEYDOWN值后得到的前兩個值,有人使用&H100和&H101作為兩個值。 我已經嘗試了其他一些我見過的隨機想法。 我只是想不出來。

哦,這是SendMessage方法

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

這是互操作常量的一個很好的站點:

的PInvoke

查找值的另一種方法是使用C#作為語言搜索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的值,而人們已經使它們變得不正常)。

看起來與你的consts略有不同。 我認為你所追求的功能是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]));
}

此外,您還需要使用SetForegroundWindow關注Chrome窗口

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM