模拟用户操作以防止系统被视为空闲的最简单方法

Posted

技术标签:

【中文标题】模拟用户操作以防止系统被视为空闲的最简单方法【英文标题】:Easiest way to simulate user action to prevent system being considered idle 【发布时间】:2013-08-15 08:42:19 【问题描述】:

我知道这个问题之前一定被问过数百次,所以,也许,我只是做错了什么。但是我正在编写一个 WinForms 程序,以尝试保持系统处于活动状态,以便将其停止为注册空闲状态。

我认为在我的表单上有一个计时器并做一些简单的事情,比如通过System.Windows.Forms.Cursor.Position 移动鼠标或使用SendKeys.Send 方法就足以注册用户交互,但它并没有注册为用户操作并且仍然让系统在设定的时间后显示为非活动状态。

我的代码相当简单......要么:

Private Sub Updater_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Updater.Tick
    SendKeys.Send("+")
End Sub

或者做一些类似的事情:

Private Sub Updater_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Updater.Tick
    Dim MyMousePosition As Point
    MyMousePosition = Windows.Forms.Cursor.Position

    Windows.Forms.Cursor.Position = New Point(MyMousePosition.X - 10, MyMousePosition.Y)
End Sub

但两者都没有做到这一点......我怎样才能让它工作,并且最好以一种对用户来说最不方便的方式工作,如果他们实际使用系统? (这意味着我不想发送一堆键,如果它们实际上处于活动状态或将鼠标移过屏幕,可能会弄乱用户)

我知道这个 coce 在 VB 中,但我擅长 VB/C# 解决方案。

谢谢!!!


编辑

作为对这个问题的补充,我使用User32.dll 中的GetLastInputInfo 来检查系统活动。

即使我的鼠标/键盘事件与Timer_Tick 事件相关联,GetLastInputInfo 只有在我物理移动鼠标/在计算机上执行某些操作时才会重置...

我想我的问题是 我可以将哪些事件添加到我的 Timer_Tick 事件中以重置 GetLastInputInfo - 换句话说,Windows 是否相信用户确实在计算机上做了某事??

谢谢!!!

【问题讨论】:

您希望系统不出现空闲的原因是什么? 我没有真正得到你想要的。 可能使用SetThreadExecutionState:***.com/questions/6302185/… 如果该程序使用低级 Windows 挂钩,您将很难欺骗它。您必须在 before 程序中挂钩您的程序,并发送模拟事件。不,我不知道该怎么做。我怀疑你不想尝试。 GetLastInputInfo 的文档表明您可以通过SendInput 函数发送信息来更新它。你试过吗? 【参考方案1】:

有一个更简单的方法,那就是调用Win32 function:

EXECUTION_STATE WINAPI SetThreadExecutionState(
  _In_  EXECUTION_STATE esFlags
);

ES_SYSTEM_REQUIRED | ES_CONTINUOUS 作为参数。 无论如何,从this SO issue看来,即使使用ES_CONTINUOUS,效果似乎也不会持续。在这种情况下,您应该定期调用该函数,比如每分钟,以重置空闲计时器。重要的是该函数只适用于调用它的线程,当线程终止时,它的作用就终止了。

完成后,您应该致电SetThreadExecutionState(ES_CONTINUOUS) 让系统再次空闲。

【讨论】:

我尝试过这样做,但没有成功,但感谢您提供的信息。【参考方案2】:

在玩了很多之后,我想出了一个可行的解决方案,我正在回答这个问题,以帮助任何可能正在寻找相同信息的人。

(VB编码):

在声明部分:

Private Declare Function SendInput Lib "user32.dll" (ByVal nInputs As Integer, ByRef pInputs As INPUT_TYPE, ByVal cbSize As Integer) As Integer
Const INPUT_MOUSE = 0
Const MOUSEEVENTF_MOVE = &H1

Public Structure MOUSEINPUT
    Public dx As Integer
    Public dy As Integer
    Public mouseData As Integer
    Public dwFlags As Integer
    Public dwtime As Integer
    Public dwExtraInfo As Integer
End Structure

Public Structure INPUT_TYPE
    Public dwType As Integer
    Public xi As MOUSEINPUT
End Structure

移动鼠标的Sub:

Public Sub MoveMouse(ByVal x As Integer, ByVal y As Integer, ByVal flag As Integer)

    Dim inputEvents As INPUT_TYPE
    Dim xi As New MOUSEINPUT

    xi.dx = x
    xi.dy = y
    xi.mouseData = 0
    xi.dwtime = 0
    xi.dwFlags = flag
    xi.dwExtraInfo = 0

    inputEvents.dwType = INPUT_MOUSE
    inputEvents.xi = xi

    SendInput(1, inputEvents, Len(inputEvents))
End Sub

Timer_Tick 事件中的代码:

Private Sub Updater_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Updater.Tick

    ' Move the mouse (relatively) 1 pixel away and then back
    MoveMouse(1, 1, MOUSEEVENTF_MOVE)
    MoveMouse(-1, -1, MOUSEEVENTF_MOVE)

End Sub

我使用GetLastInputInfo API 函数对此进行了测试,它有效!!

...我发现的最有用的链接是这个: http://homeofcox-cs.blogspot.com/2008/07/c-simulate-mouse-and-keyboard-events.html

感谢大家的帮助,我希望这对其他人也有帮助!

【讨论】:

我使用了您的解决方案,它在我的笔记本电脑上运行良好,但在我们的远程服务器上无法运行,您的解决方案有什么限制吗?【参考方案3】:

当我们需要系统不空闲时(在 WM 6.0 中,当我们有很长的逻辑并且设备空闲时,逻辑停止工作)我们使用

  [DllImport("CoreDll.dll")]
  public static extern void SystemIdleTimerReset();

它重置了空闲计时器,不干扰用户的操作,它就像魅力一样工作

【讨论】:

谢谢。就我需要的功能而言,似乎是正确的,但 CoreDll 仅适用于移动平台......对于桌面有什么想法吗??? @JohnBus​​tos 看看我为你找到了什么 - ***.com/questions/6302185/… 非常感谢您找到这个。无论出于何种原因,您会认为ES_SYSTEM_REQUIRED 标志会重置计时器(正如它所说的那样),但事实并非如此:( ...我仍然坚持这一点,似乎唯一的解决方案是SendInput 功能...如果您知道其他任何人,请告诉我!!!!该死的烦人,但谢谢这么多找我.... @JohnBus​​tos 我现在找不到它,但我记得我看到有一些寄存器值可以更改以防止空闲状态。需要的时候找不到 也是一个很酷的主意,但是网络设置已经将这些值改回了.... NUTS,嗯?? - 我现在正在研究 SendInout 解决方案......我仍然认为这将是最强大的......

以上是关于模拟用户操作以防止系统被视为空闲的最简单方法的主要内容,如果未能解决你的问题,请参考以下文章

操作系统-04-操作系统的存储管理和设备管理

如何防止Windows进入空闲状态?

模拟ATM系统 —— 用户注册登录和操用户作页设计 查询账号退出账号功能

在用户注销后防止浏览器的后退按钮显示安全数据的最简单方法是啥?

php通过记录IP来防止表单重复提交方法分析

monkeytest是啥意思