C++ 如何签入C++;系统是否处于活动状态?

C++ 如何签入C++;系统是否处于活动状态?,c++,windows,background,worker,C++,Windows,Background,Worker,我写的代码只需要在PC上没有人的活动时运行,比如屏幕保护程序运行时。在Windows下如何在C++中实现这一点? @Talnocolas,简单地说,就是使用未使用的资源,用户离开计算机但在另一个地方的次数是多少?您可以使用它来检查用户空闲了多长时间(没有移动鼠标或在键盘上键入内容),以及检查屏幕保护程序是否处于活动状态 例子 #定义WINDOWS_LEAN_和_MEAN #包括 #包括 //在用户不活动10分钟后执行某些操作 静态常量unsigned int idle_毫秒=60*10*1000

我写的代码只需要在PC上没有人的活动时运行,比如屏幕保护程序运行时。在Windows下如何在C++中实现这一点? @Talnocolas,简单地说,就是使用未使用的资源,用户离开计算机但在另一个地方的次数是多少?

您可以使用它来检查用户空闲了多长时间(没有移动鼠标或在键盘上键入内容),以及检查屏幕保护程序是否处于活动状态

例子
#定义WINDOWS_LEAN_和_MEAN
#包括
#包括
//在用户不活动10分钟后执行某些操作
静态常量unsigned int idle_毫秒=60*10*1000;
//在两次跑步之间至少等待一小时
静态常量无符号整数间隔=60*60*1000;
int main(){
LASTINPUTINFO last_输入;
BOOL屏幕保护程序处于活动状态;
//检查用户空闲时间是否足够长的主循环
对于(;;){
如果(!GetLastInputInfo(&last_input)
||!SystemParametersInfo(SPI_GETSCREENSAVERACTIVE,0,
&屏幕保护程序(活动,0))
{
标准::cerr使用系统参数信息(…)

参考:

检查一下这个看起来相似的

然而,你需要确定“不活动”的确切含义。这会改变你问题的范围

还要检查此代码

hdesk = OpenDesktop(TEXT("Screen-saver"),
                    0,
                    FALSE,
                    DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS);
if (hdesk)
{
   EnumDesktopWindows (hdesk, (WNDENUMPROC)KillScreenSaverFunc, 0);
   CloseDesktop (hdesk);
}

// ----------------------------------------------------------------

BOOL CALLBACK KillScreenSaverFunc (HWND hwnd, LPARAM lParam)
{
   PostMessage(hwnd, WM_CLOSE, 0, 0);
   return TRUE;
}

从。

这只是一个在Windows 8.1和Windows 10上测试的小更新

更改说明如下:

  • LASTINPUTINFO
    已初始化
    cbSize

  • 将选中
    SPI\u GETSCREENSAVERRUNNING
    ,而不是选中
    SPI\u GETSCREENSAVERRUNNING

  • 计算
    空闲时间
    ,并与
    空闲毫秒

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

  • 由于windows可以在4802之后立即触发事件id 4803,因此可以确定屏幕保护程序在用户空闲时仍处于打开状态,请参阅我的

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

#定义开始

#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 );
    }
}
#包括
#包括
//在用户不活动10分钟后执行某些操作
静态常量unsigned int idle_毫秒=60*10*1000;
int main(){
LASTINPUTINFO last_输入;
//未设置cbSize GetLastError()返回的参数不正确
last_input.cbSize=sizeof(last_input);
BOOL屏幕保护程序运行;
德沃德空闲时间;
bool screensaverOn=false;
//检查用户空闲时间是否足够长的主循环
对于(;;){
如果(!GetLastInputInfo(&last_input)
||!SystemParametersInfo(SPI_GETSCREENSAVERRUNNING,0,
&屏幕保护程序(正在运行,0))
{
标准::cerr用户\u空闲时间&&TRUE==屏幕保护程序\u运行)
{
如果(!screensaverOn)
{
//屏幕保护程序正在运行
screensaverOn=true;
通知(真实);
}
}
else if(空闲时间user\u空闲时间&&screensaverOn)
{
//屏幕保护程序没有运行
screensaverOn=false;
通知(虚假);
}
//在下一个循环之前等待500毫秒
睡眠(500);
}
}

无法检测服务中的用户输入是一种错误

这意味着,除其他外,服务无法直接知道上次用户输入是何时发生的,这也是
GetLastInputInfo
从服务中调用时没有返回任何有用信息的原因

显然,这个想法是为了让疯狂的黑客们的生活变得更加困难,他们试图编写密钥记录器和其他讨厌的代码。 当然,您可以通过让用户进程将该信息提供给您的服务来轻松绕过该限制。
我不认为这个琐碎的解决办法是你的普通狂热黑客所无法达到的,我更愿意想象那些家伙们正在享受这种毫无意义的代码卷积练习

如果您的服务执行用户请求的计算,您很可能需要一个用户进程来与之交互。但是,如果您想轮询任何用户活动指示,您必须让此用户进程保持运行。一个用户恶魔保持活动状态,以便向您的真实恶魔提供一点微不足道的信息。谈谈高效使用资源的分配

作为补充说明,监视屏幕保护程序的激活是非常不可靠的。屏幕可以设置为在任何保护程序出现之前关闭。电脑也可以在代码运行之前进入睡眠状态。因此,您必须更加小心检查什么情况

或者,您可能需要查看。
他们可以为您提供大量有关CPU负载、磁盘使用情况等的信息。
通过监视这些,您可以相对容易地检测到CPU和/或磁盘活动较低的时段

不过,界面非常混乱,显然还有其他安全障碍需要跨越。我不太确定哪些服务帐户(如果有的话)可以访问它们,或者在典型的Windows安装中默认情况下是否可以访问它们


您也可以在无人登录时激活代码。显然,没有明显的方法可以检测到这一点,但它是从服务内部发出的。

可能有些人对plii.dwTime感到困惑

plii.dwTime给出最后一次输入的时间戳日期,它不给出现在和最后一次输入之间的时间

为此,必须将其分为GetTickCount():

LASTINPUTINFO-plii;
plii.cbSize=sizeof(LASTINPUTINFO);
plii.dwTime=0;
如果(GetLastInputInfo(&plii)!=0)
{

cout@talnicolas:因为这是问题的一部分。你不需要重新发明轮子。只需创建一个计划任务,并在条件下指定“仅当计算机空闲[N]分钟时启动任务”。@taln
hdesk = OpenDesktop(TEXT("Screen-saver"),
                    0,
                    FALSE,
                    DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS);
if (hdesk)
{
   EnumDesktopWindows (hdesk, (WNDENUMPROC)KillScreenSaverFunc, 0);
   CloseDesktop (hdesk);
}

// ----------------------------------------------------------------

BOOL CALLBACK KillScreenSaverFunc (HWND hwnd, LPARAM lParam)
{
   PostMessage(hwnd, WM_CLOSE, 0, 0);
   return TRUE;
}
#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 );
    }
}
LASTINPUTINFO plii;
plii.cbSize = sizeof(LASTINPUTINFO);
plii.dwTime = 0;

if (GetLastInputInfo(&plii) != 0)
{
    cout << "Last activity  : " <<  GetTickCount() - plii.dwTime << " (ms)" << endl;
}
else {
    cout << "GetLastInputInfo ERROR" << endl;
}