如果系统处于活动状态,如何检入C++?

use*_*336 7 c++ windows background worker

我正在编写代码,只有当PC上没有人为活动时才需要运行,就像屏幕保护程序运行时一样.有关如何在Windows下的c ++中执行此操作的任何建议?

@talnicolas,只是使用未使用的资源,人们离开计算机多少次但是他们在另一个地方?

Nik*_* B. 11

您可以使用它GetLastInputInfo来检查用户空闲的时间(不是在鼠标周围移动或在键盘上键入内容)并SystemParametersInfo检查屏幕保护程序是否处于活动状态.

#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>

// do something after 10 minutes of user inactivity
static const unsigned int idle_milliseconds = 60*10*1000;
// wait at least an hour between two runs
static const unsigned int interval = 60*60*1000;

int main() {
    LASTINPUTINFO last_input;
    BOOL screensaver_active;

    // main loop to check if user has been idle long enough
    for (;;) {
        if ( !GetLastInputInfo(&last_input)
          || !SystemParametersInfo(SPI_GETSCREENSAVERACTIVE, 0,  
                                   &screensaver_active, 0))
        {
            std::cerr << "WinAPI failed!" << std::endl;
            return ERROR_FAILURE;
        }

        if (last_input.dwTime < idle_milliseconds && !screensaver_active) {
            // user hasn't been idle for long enough
            // AND no screensaver is running
            Sleep(1000);
            continue;
        }

        // user has been idle at least 10 minutes
        do_something();
        // done. Wait before doing the next loop.
        Sleep(interval);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我在Linux机器上编写了该代码,因此无法对其进行测试.


kri*_*ajb 6

这只是Niklas B. answer 的一个小更新,在 Windows 8.1 和 Windows 10 上进行了测试。

变更说明如下:

  • LASTINPUTINFOcbSize初始化

  • 不是检查SPI_GETSCREENSAVERACTIVESPI_GETSCREENSAVERRUNNING而是检查

  • idle_time 计算并比较 idle_milliseconds

  • 仅在更改时通知用户,每约 500 毫秒执行一次检查

  • 由于 Windows 可以在 4802 之后立即触发事件 ID 4803,因此可以确定屏幕保护程序仍在用户中idle_time,请参阅我遇到的问题

此外,这仅适用于屏幕保护程序计时器小于屏幕电源关闭计时器的情况!

#define start

#include <windows.h>
#include <iostream>

// do something after 10 minutes of user inactivity
static const unsigned int idle_milliseconds = 60*10*1000;

int main() {
    LASTINPUTINFO last_input;
    // without setting cbSize GetLastError() returns the parameter is incorrect
    last_input.cbSize = sizeof(last_input);  
    BOOL screensaver_running;

    DWORD idle_time;
    bool screensaverOn = false;

    // main loop to check if user has been idle long enough
    for (;;) {
        if ( !GetLastInputInfo( &last_input )
          || !SystemParametersInfo( SPI_GETSCREENSAVERRUNNING, 0,  
                               &screensaver_running, 0 ) )
        {
            std::cerr << "WinAPI failed!" << std::endl;
            return ERROR_FAILURE;
        }

        // calculate idle time
        idle_time = GetTickCount() - last_input.dwTime;

        if ( idle_time > this->user_idle_time && TRUE == screensaver_running )
        {
            if ( !screensaverOn )
            {
                // screensaver is running
                screensaverOn = true;
                notify( true );
            }
        }
        else if ( idle_time < this->user_idle_time && screensaverOn )
        {
            // screensaver is not running
            screensaverOn = false;
            notify( false );
        }
        // wait 500ms before next loop
        Sleep( 500 );
    }
}
Run Code Online (Sandbox Code Playgroud)