【问题标题】:C# - Sending messages to Google Chrome from C# applicationC# - 从 C# 应用程序向 Google Chrome 发送消息
【发布时间】:2008-09-29 08:25:35
【问题描述】:

我一直在四处寻找,但我还没有找到如何从 C# 中做到这一点。

我想这样做是为了让 Chrome 浏览器前进后退打开新标签关闭我的 C# 应用程序中的选项卡打开新窗口关闭窗口

我使用 WinAmp 做了类似的事情

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

还有一些其他的。但我不知道要发送什么消息或如何找到将其传递到哪个窗口或任何东西。

那么有人可以告诉我如何将这 6 个命令从 C# 发送到 Chrome 吗?谢谢

编辑: 好的,我被否决了,所以也许我不够清楚,或者人们认为我没有尝试自己解决这个问题。

首先,我对整个 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);

我假设我会为谷歌浏览器做一些与此非常相似的事情。但我不知道其中一些值应该是什么,我四处搜索试图找到答案,但我做不到,这就是我在这里问的原因。所以我的问题是如何获得以下值:

m_windowNameWM_COMMAND

然后是不同命令的值,forwardbacknew tabclose tab , 新窗口, 关闭窗口?

【问题讨论】:

    标签: c# google-chrome message


    【解决方案1】:

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


    编辑:向窗口发送消息只是工作的一半。窗口必须响应该消息并采取相应措施。如果该窗口不知道消息或根本不关心,您就没有机会通过发送窗口消息来控制它。

    您正在查看有关如何远程控制 Winamp 的实施细节。发送消息只是其中一种方式,也是 Winamp 开发人员选择的方式。您正在使用的这些消息是用户定义的消息,对 Winamp 具有特定含义。

    第一步你要做的是找出如果 Chromium 支持某种远程控制以及那些机制是什么。

    【讨论】:

    • 我正在查看,但没有看到任何可以帮助我完成我想做的事情的东西。我不想重新编译 Chrome 或任何东西。我只想能够向 Chrome 发送一条小消息,说“回去”或其他什么。我根本不想更改 Chrome。全部从 C# 完成
    【解决方案2】:

    您可以使用 Visual Studio 的 Spy++ 并按 CTRL+F 轻松获取窗口名称,然后找到 chrome。我试过了,得到了

    “Chrome_VistaFrame”用于外窗。包含网页的实际窗口是“Chrome_RenderWidgetHostHWND”。

    就 WM_COMMAND 而言,您需要进行试验。您显然希望发送按钮点击(我头顶的 WM_MOUSEDOWN)。由于后退,前进按钮不是它们自己的窗口,您需要弄清楚如何通过在某个 x,y 位置模拟鼠标单击来做到这一点,以便 chrome 知道您在做什么。或者您可以发送等效于后退/前进等的键盘快捷键。

    我不久前写的一个例子是用 trillian 和 winamp 做的:sending messages to windows via c# and winapi

    还有一些工具可以使用脚本语言来宏化这类事情 - 我用过 autoit:autoit.com

    【讨论】:

    • 所以我玩了这个一两个小时。我想发送键盘快捷键。现在我正试图弄清楚如何向 Chrome 发送 WM_KEYDOWN 的消息和 VK_BROWSER_BACK 键的 WM_KEYUP 消息。但我不知道它们的 int 值。
    【解决方案3】:

    好的,这就是我目前所做的……我有点知道我需要做什么,但现在就做吧……

    这是 Spy++ 的窗口,我锁定了 Chrome_RenderWidgetHostHWND 并单击了键盘上的后退按钮。这是我得到的:

    所以这是我的假设,我现在一直在玩这个,我只是无法弄清楚

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

    【讨论】:

      【解决方案4】:

      这是一个很好的互操作常量站点:

      pinvoke

      另一种查找值的方法是搜索 koders.com,使用 C# 作为语言,查找 WM_KEYDOWN 或您所追求的常量:

      Koders.com search

      &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_* 是 1 字节的 0-255 值,并且人们已经将它们设为 uint,有多少 VK 常量的错误定义在浮动)。

      看起来与您的 const 略有不同。我认为您所追求的功能是 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 窗口

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-04
        • 2012-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多