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

时间:2013-08-13 16:10:28

标签: c# vb.net winforms

我知道这个问题之前肯定已被问过几百次,所以,也许,我只是做错了什么。但我有一个WinForms程序,我试着让系统保持活动状态,以便在注册空闲时停止它。

我认为在我的表单上安装一个Timer并做一些像通过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#解决方案很好。

感谢!!!


修改

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

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

我想我的问题是 我可以将哪些事件添加到我的Timer_Tick事件中,该事件将重置GetLastInputInfo - 换句话说,让Windows认为用户实际上在机器上做了什么事情?

感谢!!!

3 个答案:

答案 0 :(得分:7)

经过大量的游戏,我想出了一个有效的解决方案,我正在回答这个问题,以便帮助那些可能正在寻找相同信息的人。

(用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

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

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

有一种更简单的方法,即调用Win32 function

EXECUTION_STATE WINAPI SetThreadExecutionState(
  _In_  EXECUTION_STATE esFlags
);

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

完成后,您应该拨打SetThreadExecutionState(ES_CONTINUOUS)以允许系统再次闲置。