C# 如何检测进程是否移动了鼠标光标而不是用户?

C# 如何检测进程是否移动了鼠标光标而不是用户?,c#,winforms,winapi,mouseevent,C#,Winforms,Winapi,Mouseevent,可以通过使用属性来移动调用或的鼠标。我想知道的是,是否有可能知道使用我的软件的用户是否在使用这些方法之一 我知道可以检查用户的鼠标移动,例如,查看是否发生过快。但我想知道是否还有其他更准确的方法,比如检查某个WinApi函数是否被调用 当鼠标实际移动时,是否触发了鼠标事件功能 或者对鼠标事件函数的调用是否会进行另一个系统调用,并调用“物理鼠标移动”使用的实际函数?我认为,如果另一个进程通过代码更改光标位置,并且不是用户移动光标,则不会发出警告,除非某个通过代码移动光标的WinAPI具有可以更改的

可以通过使用属性来移动调用或的鼠标。我想知道的是,是否有可能知道使用我的软件的用户是否在使用这些方法之一

我知道可以检查用户的鼠标移动,例如,查看是否发生过快。但我想知道是否还有其他更准确的方法,比如检查某个WinApi函数是否被调用

当鼠标实际移动时,是否触发了鼠标事件功能


或者对鼠标事件函数的调用是否会进行另一个系统调用,并调用“物理鼠标移动”使用的实际函数?

我认为,如果另一个进程通过代码更改光标位置,并且不是用户移动光标,则不会发出警告,除非某个通过代码移动光标的WinAPI具有可以更改的事件,否则这是可能的注册的

我测试过,如果代码更改光标位置,WinForm或使用全局钩子不会引发MouseMove

因此,使用GetLastInputInfo不起作用,并且似乎无法检测进程是否更改了移动位置

这就是说,你可以使用一个带有MouseMove全局钩子的计时器

  • 在应用程序启动时,将鼠标位置保存为上一个位置

  • 例如,启动一个间隔为100ms的计时器

  • 在MouseMove上,您将更新此先前位置并将条件变量设置为true

  • 在计时器刻度上,您将获得当前位置,并将其与previous和条件变量进行比较:如果它不相同,则移动的不是用户

它很重,但能用

如果用户在一个进程中同时移动鼠标,您只会得到移动的是用户

使用WinForms计时器

public partial class FormTest : Form
{
System.Threading.Timer TimerCheckMouseMove;

TimerCheckMouseMove = new System.Threading.Timer(TimerCheckMouseMove_Tick, null, 0, 100);

private bool TimerCheckMouseMoveMutex;

private void TimerCheckMouseMove_Tick(object state)
{
  if ( TimerCheckMouseMoveMutex ) return;
  TimerCheckMouseMoveMutex = true;
  try
  {
    var pos = Cursor.Position;
    if ( !UserMovedMouse && pos != PreviousMousePosition)
      MessageBox.Show("Mouse moved by a process");
    PreviousMousePosition = Cursor.Position;
    UserMovedMouse = false;
  }
  finally
  {
    TimerCheckMouseMoveMutex = false;
  }
}
使用线程计时器

public partial class FormTest : Form
{
System.Threading.Timer TimerCheckMouseMove;

TimerCheckMouseMove = new System.Threading.Timer(TimerCheckMouseMove_Tick, null, 0, 100);

private bool TimerCheckMouseMoveMutex;

private void TimerCheckMouseMove_Tick(object state)
{
  if ( TimerCheckMouseMoveMutex ) return;
  TimerCheckMouseMoveMutex = true;
  try
  {
    var pos = Cursor.Position;
    if ( !UserMovedMouse && pos != PreviousMousePosition)
      MessageBox.Show("Mouse moved by a process");
    PreviousMousePosition = Cursor.Position;
    UserMovedMouse = false;
  }
  finally
  {
    TimerCheckMouseMoveMutex = false;
  }
}

可以使用API调用
SendInput()
mouse\u event()
检测鼠标输入是否由代码生成。要执行此操作,请使用
SetWindowsHookEx()
设置一个。此钩子过程被传递给一个
标志
成员,该成员指示鼠标事件是由代码注入的结果,还是用户输入的结果

如果攻击者向您的应用程序发送鼠标消息,您可以从鼠标消息处理程序调用。真正的鼠标消息将发布到消息队列。通常会发送假鼠标消息。如果
InSendMessage
返回
TRUE
,则可以确定您收到了一条假输入消息。如果攻击者确实发布消息,您将不得不依靠识别实际输入设备状态与预期状态之间的不匹配。可以用于此


无法立即检测对
SetCursorPos
的调用。孤立地说,这些调用不会生成用户输入,并且不能用于自动化应用程序。它们总是伴随着其他注入输入的方案,您知道如何识别这些方案。

欢迎使用StackOverflow。感谢您抽出时间分享您的问题。你要什么还不清楚。你的目标和困难是什么?到目前为止你做了什么?请尝试更好地解释您的问题、您的开发环境和数据结构,并共享更多代码(无屏幕截图)、屏幕图像或草图以及用户故事或场景图。为了帮助您改进您的请求,请阅读右上角的和我避免问的问题。@OlivierRogier您好!谢谢你的反馈。我将通过编辑使问题更清楚。我已经阅读了你发布的链接,其中有一部分说“并非所有问题都能从包含代码中受益。”这也适用于我的问题。我不理解这个问题。所有文本,尤其是如果有可能知道用户是否在使用这些方法之一。您想知道如何移动光标,如何检测光标是否移动,或者另一个进程是否对此进行了操作。。。澄清问题并添加代码或图表可能有助于了解您试图做什么。@OlivierRogier我试图以不同的方式询问我的编辑。我没有代码可以显示,因为我正在尝试了解这是否可能。我希望得到这样的回答:“这是不可能的,鼠标的实际移动调用的函数与用户在代码中可以调用的函数相同”,或者回答“这是可能的,查看进程句柄,看看它们指向什么”。相关:这能通过代码而不是用户来检测鼠标移动吗?它是如何工作的这个链接提到“钩子甚至不知道哪个应用程序将实际接收密钥,因为钩子是在从硬件队列中删除击键之后,在操作系统确定接收应用程序之前调用的”,所以你所说的可能是不可能的。我的回答是回应官方文档。如果您有理由相信API文档承诺的内容和API提供的内容不是一回事,请提交文档缺陷问题。然而,更可能的是,你所要求的和你需要解决的问题不是一回事。我回答了你问的问题。@IInspectable另一方面,低级鼠标钩子只检测通过硬件队列的事件,甚至是注入的事件,但它不检测不通过硬件队列的
SetCursorPos()
queue@rem:
SetCursorPos
不严格生成用户输入。它本身不能用于自动化应用程序。在犯罪中总是需要兄弟,而且这些兄弟是可以识别的。这就是忽略了
WM\u MOUSEMOVE
消息的真正工作原理:。
  private void TimerCheckMouseMove_Tick(object sender, EventArgs e)
  {
    TimerCheckMouseMove.Enabled = false;
    try
    {
      var pos = Cursor.Position;
      if ( !UserMovedMouse && pos != PreviousMousePosition)
        MessageBox.Show("Mouse moved by a process");
      PreviousMousePosition = Cursor.Position;
      UserMovedMouse = false;
    }
    finally
    {
      TimerCheckMouseMove.Enabled = true;
    }
  }
  private void TimerMoveMouse_Tick(object sender, EventArgs e)
  {
    Cursor.Position = new Point(100, 100);
  }
}
System.Threading.Timer TimerCheckMouseMove;

TimerCheckMouseMove = new System.Threading.Timer(TimerCheckMouseMove_Tick, null, 0, 100);

private bool TimerCheckMouseMoveMutex;

private void TimerCheckMouseMove_Tick(object state)
{
  if ( TimerCheckMouseMoveMutex ) return;
  TimerCheckMouseMoveMutex = true;
  try
  {
    var pos = Cursor.Position;
    if ( !UserMovedMouse && pos != PreviousMousePosition)
      MessageBox.Show("Mouse moved by a process");
    PreviousMousePosition = Cursor.Position;
    UserMovedMouse = false;
  }
  finally
  {
    TimerCheckMouseMoveMutex = false;
  }
}