我想在我的C#程序中模拟按下 F5 键。当IE浏览器打开时,我希望能够自动刷新我的网站。
我该如何实现?
我想在我的C#程序中模拟按下 F5 键。当IE浏览器打开时,我希望能够自动刷新我的网站。
我该如何实现?
这里有一个例子...
static class Program
{
[DllImport("user32.dll")]
public static extern int SetForegroundWindow(IntPtr hWnd);
[STAThread]
static void Main()
{
while(true)
{
Process [] processes = Process.GetProcessesByName("iexplore");
foreach(Process proc in processes)
{
SetForegroundWindow(proc.MainWindowHandle);
SendKeys.SendWait("{F5}");
}
Thread.Sleep(5000);
}
}
}
一个更好的,不那么烦人的...
static class Program
{
const UInt32 WM_KEYDOWN = 0x0100;
const int VK_F5 = 0x74;
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
[STAThread]
static void Main()
{
while(true)
{
Process [] processes = Process.GetProcessesByName("iexplore");
foreach(Process proc in processes)
PostMessage(proc.MainWindowHandle, WM_KEYDOWN, VK_F5, 0);
Thread.Sleep(5000);
}
}
}
FindWindow
或FindWindowEx来查找打开的浏览器窗口句柄,然后只需使用SendMessage和WM_KEYDOWN发送按键消息。通常最简单的方法是将窗口标题传递给FindWindowEx
,让它为您查找关联的窗口句柄。Process process
对象启动浏览器进程,则可以使用process.MainWindowHandle
代替调用FindWindowEx
。const int VK_F5 = 0x74;
FindWindowEx
在 C# 中的 p/invoke 签名为:
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
您可以通过p/invoke(导入)Win32 API SendMessage
来实现:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
简单总结一下,你需要在你的C#代码中调用FindWindowEx
函数,在类中的某个位置。 FindWindowEx
将会返回一个窗口句柄。一旦你有了窗口句柄,你可以向窗口发送任何按键或者调用许多其他Win32 API来处理窗口句柄。甚至可以使用另一个调用FindWindowEx
来查找子窗口。例如,你可以选择浏览器的编辑控件,然后更改它的文本。
如果一切都出了问题,你认为自己已经向窗口发送了正确的按键,那么可以使用spy++
工具查看当你手动设置焦点到浏览器并手动按下时,发送到窗口的消息。
SendMessage
中的属性应该是什么? - emilazSendKeys.Send("{F5}");
可以使用mouse_event或keybd_event。虽然有人说不再建议使用它们,但是你根本不需要找到窗口。
using System;
using System.Runtime.InteropServices;
public class SimulatePCControl
{
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void keybd_event(uint bVk, uint bScan, uint dwFlags, uint dwExtraInfo);
private const int VK_LEFT = 0x25;
public static void LeftArrow()
{
keybd_event(VK_LEFT, 0, 0, 0);
}
}
这里提供一些虚拟按键码的列表:http://www.kbdedit.com/manual/low_level_vk_list.html
另外,还有一些关于鼠标的:
using System.Runtime.InteropServices;
using UnityEngine;
public class SimulateMouseClick
{
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);
//Mouse actions
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
private const int MOUSEEVENTF_RIGHTUP = 0x10;
public static void Click()
{
//Call the imported function with the cursor's current position
uint X = (uint)0;
uint Y = (uint)0;
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
Debug.LogError("SIMULATED A MOUSE CLICK JUST NOW...");
}
//...other code needed for the application
}
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
主函数/方法内的代码:
string className = "IEFrame";
string windowName = "New Tab - Windows Internet Explorer";
IntPtr IE = FindWindow(className, windowName);
if (IE == IntPtr.Zero)
{
return;
}
SetForegroundWindow(IE);
InputSimulator.SimulateKeyPress(VirtualKeyCode.F5);
注意:
简单、短小,无需窗口焦点:
此外这里有一个有用的虚拟键代码列表
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
private void button1_Click(object sender, EventArgs e)
{
const int WM_SYSKEYDOWN = 0x0104;
const int VK_F5 = 0x74;
IntPtr WindowToFind = FindWindow(null, "Google - Mozilla Firefox");
PostMessage(WindowToFind, WM_SYSKEYDOWN, VK_F5, 0);
}
当您只是想让页面回传而不是强制按下F5键时,您可以基于JS事件(甚至是mousemove或timer_tick,如果您希望它始终触发)调用回传。请使用http://weblogs.asp.net/mnolton/archive/2003/06/04/8260.aspx上的代码作为参考。