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

我想要做到这一点,这样我就可以告诉 Google 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;

我会得到 汉德 (将消息发送到的程序)通过:

IntPtr hwnd = FindWindow(m_windowName, null);

然后我会向该程序发送一条消息:

SendMessageA(hwnd, WM_COMMAND, WA_STOP, WA_NOTHING);

我想我会为 Google Chrome 做一些非常类似的事情。但我不知道其中一些值应该是什么,我用谷歌搜索试图找到答案,但我找不到,这就是我在这里问的原因。所以我的问题是如何获取以下值:

m_窗口名称WM_命令

然后,不同命令的值, 向前, 后退, 新标签, 关闭选项卡, 新窗户, 关闭窗口?

有帮助吗?

解决方案

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


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

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

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

其他提示

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

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

就 WM_COMMAND 而言 - 您需要进行试验。显然你会想要发送按钮点击(我头上的WM_MOUSEDOWN)。由于后退、前进按钮不是它们自己的窗口,因此您需要弄清楚如何通过在某个 x、y 位置模拟鼠标单击来实现此操作,以便 chrome 知道您在做什么。或者您可以发送相当于后退/前进等的键盘快捷键。

我不久前写的一个例子是用 trillian 和 winamp 来实现这一点的: 通过c#和winapi向windows发送消息

还有一些工具可以使用脚本语言来宏化此类事情 - autoit 是我使用过的一种: 汽车网站

好吧,这就是我到目前为止所得到的......我有点知道我需要做什么,但现在只是做的问题......

这是 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;

后两个值是我从刚刚显示的图像中获得的,即这两个键的扫描代码。我不知道我是否做对了。前两个值是我在谷歌搜索 WM_KEYDOWN 值后得到的,有人使用 &H100 和 &H101 作为这两个值。我还尝试过其他一些我见过的随机想法。我就是想不通。

哦,这是 SendMessage 方法

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

这是一个很棒的互操作常量网站:

平沃克

查找值的另一种方法是使用 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_* 是 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]));
}

此外,您还需要使用以下命令将 Chrome 窗口聚焦 设置前景窗口

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top