需要使用 C# 刷新 chrome 浏览器

Posted

技术标签:

【中文标题】需要使用 C# 刷新 chrome 浏览器【英文标题】:Need to refresh chrome browser using C# 【发布时间】:2014-12-10 09:14:37 【问题描述】:

在单击按钮时的 Windows 应用程序中,我需要刷新所有打开的 Chrome 浏览器实例,或者至少刷新我机器上的“活动”选项卡。

我的代码如下:

 [DllImport("user32.dll")]
 static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
 private void btnGetBrowserProcess_Click(object sender, EventArgs e)
    
       const UInt32 WM_KEYDOWN = 0x0100;
       const int VK_F5 = 0x74;

        Process[] procsChrome = Process.GetProcessesByName("chrome");
        foreach (Process chrome in procsChrome)
        
            if (chrome.MainWindowHandle != IntPtr.Zero)
            
               PostMessage(chrome.MainWindowHandle, WM_KEYDOWN, VK_F5, 0);
            
        

这适用于 IE 和 Mozilla,但不适用于 Chrome

【问题讨论】:

Chrome 将页面创建为可能导致问题的单独进程 但我无法将刷新命令传递给任何 chrome 进程 有什么理由不使用 WebDriver + ChromeDriver? code.google.com/p/selenium/wiki/ChromeDriver sites.google.com/a/chromium.org/chromedriver/getting-started 【参考方案1】:

尝试改用SendInput 命令。不幸的是,这意味着您需要添加更多代码来进行设置,并且您还需要在发送按键之前将焦点设置在 chrome 窗口上。

两个必需的外部函数是:

    [DllImport("user32.dll")]
    static extern bool SetForegroundWindow(IntPtr hWnd);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern uint SendInput(uint numberOfInputs, INPUT[] inputs, int sizeOfInputStructure);

那么需要的structs是:

    /// <summary>
    /// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646270(v=vs.85).aspx
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    internal struct INPUT
    
        public uint Type;
        public MOUSEKEYBDHARDWAREINPUT Data;
    

    /// <summary>
    /// http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/f0e82d6e-4999-4d22-b3d3-32b25f61fb2a
    /// </summary>
    [StructLayout(LayoutKind.Explicit)]
    internal struct MOUSEKEYBDHARDWAREINPUT
    
        [FieldOffset(0)]
        public HARDWAREINPUT Hardware;
        [FieldOffset(0)]
        public KEYBDINPUT Keyboard;
        [FieldOffset(0)]
        public MOUSEINPUT Mouse;
    

    /// <summary>
    /// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646310(v=vs.85).aspx
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    internal struct HARDWAREINPUT
    
        public uint Msg;
        public ushort ParamL;
        public ushort ParamH;
    

    /// <summary>
    /// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646310(v=vs.85).aspx
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    internal struct KEYBDINPUT
    
        public ushort Vk;
        public ushort Scan;
        public uint Flags;
        public uint Time;
        public IntPtr ExtraInfo;
    

    /// <summary>
    /// http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/2abc6be8-c593-4686-93d2-89785232dacd
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    internal struct MOUSEINPUT
    
        public int X;
        public int Y;
        public uint MouseData;
        public uint Flags;
        public uint Time;
        public IntPtr ExtraInfo;
    

然后最后改变你的点击事件:

private void btnGetBrowserProcess_Click(object sender, EventArgs e)

        Process[] procsChrome = Process.GetProcessesByName("chrome");
        foreach (Process chrome in procsChrome)
        
            if (chrome.MainWindowHandle != IntPtr.Zero)
            
                // Set focus on the window so that the key input can be received.
                SetForegroundWindow(chrome.MainWindowHandle);

                // Create a F5 key press
                INPUT ip = new INPUT  Type  =1;
                ip.Data.Keyboard = new KEYBDINPUT();
                ip.Data.Keyboard.Vk = (ushort)0x74;  // F5 Key
                ip.Data.Keyboard.Scan = 0;
                ip.Data.Keyboard.Flags = 0;
                ip.Data.Keyboard.Time = 0;
                ip.Data.Keyboard.ExtraInfo = IntPtr.Zero;

                var inputs = new INPUT[]  ip ;

                // Send the keypress to the window
                SendInput(1, inputs, Marshal.SizeOf(typeof(INPUT)));

                // probably need to set focus back to your application here.
            
        

我自己试过了,我打开的当前 Chrome 标签页已成功刷新。我使用以下内容作为参考构建了这个示例:

http://batchloaf.wordpress.com/2012/04/17/simulating-a-keystroke-in-win32-c-or-c-using-sendinput/ Send keys through SendInput in user32.dll

很遗憾,我没有解释为什么 PostMessage 不适用于 Chrome,但我怀疑这与它的构建方式有关。

【讨论】:

感谢这个优秀的代码,我可以将注意力集中在 chrome 浏览器上,即使浏览器被最小化,它也能正常工作,我需要你的更多帮助,有什么办法可以刷新浏览器的所有标签页,包括 IE 和 Mozilla 我能想到的唯一方法是通过 win32 api 发送一个 Ctrl+Tab 按键,然后是 F5,但是没有办法可靠地知道这需要多少次在没有先验知识的情况下完成,因为每个浏览器实现其选项卡的方式不同,并且这些信息不太可能访问。如果您想比上面的示例更先进,那么您可能应该考虑创建浏览器扩展,以允许您的应用程序与浏览器对话并执行您需要的操作。 现在我可以通过在 f5 之后发送 Ctrl+Tab 来刷新所有浏览器选项卡,感谢您的建议 好的,我会说它会对正在执行 Windows 服务的帐户的安全上下文有所影响。它可能无法访问 MainWindowHandle 只是因为它没有权限。 我的建议是在 *** 上发布一个新问题,询问是否有解决问题的方法,因为它与您的原始问题不同。这样你就可以得到比我更多的答案。不要忘记提供问题的详细信息和背景,以便人们有足够的信息来帮助您。

以上是关于需要使用 C# 刷新 chrome 浏览器的主要内容,如果未能解决你的问题,请参考以下文章

Chrome浏览器如何强制刷新

C# Chrome内核

C#将WebBowser控件替换为Chrome内核

用C#破解Chrome浏览器cookie值

打开chrome之后网页总是自动刷新,怎么解决

在 C# App 中嵌入 Chrome 浏览器使用 CefSharp