【问题标题】:Simulating Key Press C#模拟按键 C#
【发布时间】:2011-03-04 02:33:40
【问题描述】:

我想在我的 C# 程序中模拟 F5 按键。当 IE 打开时,我希望能够自动刷新我的网站。

我该怎么做?

【问题讨论】:

  • 这是网络应用还是桌面应用?
  • 在这种情况下,我认为邦迪先生一针见血。

标签: c#


【解决方案1】:

这是一个例子......

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

【讨论】:

  • 这个(尤其是“更好”的那个)帮助了我,+1。请参阅我的回答 here 以查看更复杂的示例,该示例还涉及修饰键。
【解决方案2】:

您可以使用 Win32 API FindWindow 或 FindWindowEx 找到打开的浏览器的窗口句柄,然后只需调用 SendMessage 和 WM_KEYDOWN。通常,将窗口标题传递给FindWindowEx 并让它为您找到相关的窗口句柄是最简单的。

如果您通过Process process 对象自己启动浏览器进程,那么您可以使用process.MainWindowHandle 而不是调用FindWindowEx。

当您想开始使用其他窗口时,Spy++ 是一个非常有用的工具。它基本上允许您学习另一个程序的 UI 元素层次结构。您还可以监控进入您正在监控的窗口的所有消息。我有更多信息this thread。

F5 键击有这个虚拟键码:

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/调用(引入)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++ 来查看当您手动将焦点设置到浏览器并手动按@987654341 时将哪些消息发送到窗口@。

【讨论】:

  • 能不能说的详细点,我真的不知道怎么用Win32 API。
  • SO 线程的链接非常完美。但也许这个 sn-p 可能会有所帮助 - snippets.dzone.com/posts/show/4070
  • @Dani:我添加了更多信息,但您可以使用 lang:c# 搜索 Google 代码搜索以获取更详细的示例。 google.com/…
【解决方案3】:

向任何窗口发送(模拟)KeyStroke 的最简单方法是使用 .NET Framework 的 SendKeys.Send 方法。

查看这篇非常直观的 MSDN 文章 http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx


特别是对于您的情况,如果您的浏览器窗口处于焦点位置,则发送 F5 将只涉及以下代码行:

SendKeys.Send("{F5}");

【讨论】:

  • SendKeys 未定义
  • 添加对 System.Windows.Forms 的引用。
【解决方案4】:

简单的一个,在Main之前添加

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

Main/Method 内的代码:

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

注意:

  1. 添加 InputSimulator 作为参考。下载Click here

  2. 要查找类和窗口名称,请使用 WinSpy++。下载Click here

【讨论】:

    【解决方案5】:

    模拟 F5 按键的另一种替代方法是在 Window Forms 应用程序中简单地托管 WebBrowser 控件。您使用WebBrowser.Navigate 方法加载您的网页,然后使用标准的Timer 并在计时器的每个滴答声中重新导航到将重新加载页面的网址。

    【讨论】:

      【解决方案6】:

      当您只是试图让页面回发时,您可以调用基于 JS 事件的回发(甚至是 mousemove 或 timer_tick,如果您希望它触发,也可以调用回发,而不是强制 F5 按键)每时每刻)。使用http://weblogs.asp.net/mnolton/archive/2003/06/04/8260.aspx 处的代码作为参考。

      【讨论】:

        【解决方案7】:

        简单、简短且无需窗口焦点:

        还有here 一个有用的虚拟键代码列表

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

        【讨论】:

          【解决方案8】:

          使用 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
          }
          

          【讨论】:

            猜你喜欢
            • 2020-04-29
            • 2011-11-10
            • 2012-02-15
            • 2021-03-07
            • 1970-01-01
            • 1970-01-01
            • 2011-03-23
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多