【问题标题】:System idle time - Windows service系统空闲时间 - Windows 服务
【发布时间】:2012-03-20 21:34:22
【问题描述】:

我正在开发一个 Windows 服务,它需要知道本地机器空闲了多长时间。我已经尝试过标准的 Qt 方法,但是由于 Service 作为 LocalSystem 运行,它不会注册本地用户活动。

当应用程序作为 LocalSystem 运行时,关于如何获取机器空闲状态的任何想法?

【问题讨论】:

  • 我假设您会在确定空闲时间之前检测是否有用户登录...
  • Cassia 似乎只适用于终端服务器,而不是本地机器......

标签: c# windows-services


【解决方案1】:

不确定这是否有帮助。来自文章:here

由于我们使用的是非托管库,所以首先是附加的 using 语句:

using System.Runtime.InteropServices;

// Unmanaged function from user32.dll    
[DllImport("user32.dll")]    
static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
// Struct we'll need to pass to the function    
internal struct LASTINPUTINFO    
{    
    public uint cbSize;    
    public uint dwTime;    
}

private void tmrIdle_Tick(object sender, EventArgs e)    
{    
    // Get the system uptime    
    int systemUptime = Environment.TickCount;    
    // The tick at which the last input was recorded    
    int LastInputTicks = 0;    
    // The number of ticks that passed since last input    
    int IdleTicks = 0;            
    // Set the struct    
    LASTINPUTINFO LastInputInfo = new LASTINPUTINFO();    
    LastInputInfo.cbSize = (uint)Marshal.SizeOf(LastInputInfo);    
    LastInputInfo.dwTime = 0;       

    // If we have a value from the function    
    if (GetLastInputInfo(ref LastInputInfo))    
    {    
        // Get the number of ticks at the point when the last activity was seen    
        LastInputTicks = (int)LastInputInfo.dwTime;    
        // Number of idle ticks = system uptime ticks - number of ticks at last input    
        IdleTicks = systemUptime - LastInputTicks;    
    }        

    // Set the labels; divide by 1000 to transform the milliseconds to seconds    
    lblSystemUptime.Text = Convert.ToString(systemUptime / 1000) + " seconds";    
    lblIdleTime.Text = Convert.ToString(IdleTicks / 1000) + " seconds";    
    lblLastInput.Text = "At second " + Convert.ToString(LastInputTicks / 1000);    
}

【讨论】:

  • 我试过了,但它似乎查看了 LocalSystem 的不活动状态,并报告系统自启动以来一直处于非活动状态...
  • 如果您查看我对您的问题的第一条评论,您会发现它使用相同的代码,但会在用户登录时启动此过程。绝对是重复的问题。
【解决方案2】:

我找到了两个选项。

用户模式助手。

  1. 它调用GetLastInputInfo()
  2. 可以注册为任务计划任务。它应该像守护进程一样持续运行。
  3. 要与服务进行通信,它可以使用写入文件、服务 HTTP 以及可能的其他 IPC 方法。

WTSAPI + CreateProcessAsUser() + 用户模式助手。

  1. 助手调用GetLastInputInfo()
  2. 但在这种情况下,它不必一直运行。
  3. 该服务使用 WTSAPI 找到一个活动的用户会话,并使用 CreateProcessAsUser() 运行帮助程序。

为什么进入用户会话很复杂以及如何做到这一点: https://web.archive.org/web/20211106110931/https://3735943886.com/?p=80 https://stackoverflow.com/a/35297713/633969

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-02
    • 2011-04-24
    • 1970-01-01
    • 2011-03-06
    • 2019-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多