0

我需要使用 c# 应用程序从服务器 pc 中找出远程 pc 的空闲时间。我有一个在局域网中连接的 IP 地址和主机名列表。我想找出 LAN 中连接的每台计算机的空闲时间超过 30 分钟。我为本地电脑完成了它,但它不适用于远程电脑。这是我的本地电脑代码。

[DllImport("user32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

 private int GetIdleTime()
{
    LASTINPUTINFO lastone = new LASTINPUTINFO();
    lastone.cbSize = (uint)Marshal.SizeOf(lastone);
    lastone.dwTime = 0;

    int idleTime = 0;

    int tickCount = Environment.TickCount;
    if (GetLastInputInfo(ref lastone))
    {
        idleTime = tickCount - (int)lastone.dwTime;
        return idleTime;
    }
    else
        return 0;
}
4

3 回答 3

1

根据MSDN,这对于本地机器来说是不可能的,更不用说远程机器了。

此功能对于输入空闲检测很有用。但是,GetLastInputInfo 不提供跨所有正在运行的会话的系统范围的用户输入信息。相反,GetLastInputInfo 仅为调用该函数的会话提供特定于会话的用户输入信息。

但是,您可以尝试以下方法之一:

  • 在每台 PC 上都有一个可以查询的进程。
  • 在每台 PC 上都有一个进程向您的中央进程报告。
  • 监控远程 PC 进程以确定屏幕保护程序是否处于活动状态。

如果您没有停用终端服务,并且客户端是 xp 或更高版本,您也可以使用

ITerminalServicesSession.LastInputTime

为此,您可以使用 Cassia 库或 p/invoke

WTS查询会话信息

于 2013-03-24T13:53:58.403 回答
1

我使用这个远程 WMI 查询:

object idleResult = Functions.remoteWMIQuery(machinename, "", "", "Select CreationDate From Win32_Process WHERE Name = \"logonUI.exe\"", "CreationDate", ref wmiOK);

Logonui.exe 是锁屏。在业务环境中,大多数系统会在用户空闲时锁定。

您可以像这样以 DateTime 格式翻译结果

DateTime idleTime = Functions.ParseCIM_DATETIME((string)idleResult);

ParseCIM_DATETIME 是这个功能:

public static DateTime ParseCIM_DATETIME(string date)
    {
        //datetime object to store the return value
        DateTime parsed = DateTime.MinValue;

        //check date integrity
        if (date != null && date.IndexOf('.') != -1)
        {
            //obtain the date with miliseconds
            string newDate = date.Substring(0, date.IndexOf('.') + 4);

            //check the lenght
            if (newDate.Length == 18)
            {
                //extract each date component
                int y = Convert.ToInt32(newDate.Substring(0, 4));
                int m = Convert.ToInt32(newDate.Substring(4, 2));
                int d = Convert.ToInt32(newDate.Substring(6, 2));
                int h = Convert.ToInt32(newDate.Substring(8, 2));
                int mm = Convert.ToInt32(newDate.Substring(10, 2));
                int s = Convert.ToInt32(newDate.Substring(12, 2));
                int ms = Convert.ToInt32(newDate.Substring(15, 3));

                //compose the new datetime object
                parsed = new DateTime(y, m, d, h, mm, s, ms);
            }
        }

        //return datetime
        return parsed;
    }

远程 WMI 查询功能如下:

public static object remoteWMIQuery(string machine, string username, string password, string WMIQuery, string property, ref bool jobOK)
    {
        jobOK = true;
        if (username == "")
        {
            username = null;
            password = null;
        }
        // Configure the connection settings.
        ConnectionOptions options = new ConnectionOptions();
        options.Username = username; //could be in domain\user format
        options.Password = password;
        ManagementPath path = new ManagementPath(String.Format("\\\\{0}\\root\\cimv2", machine));
        ManagementScope scope = new ManagementScope(path, options);

        // Try and connect to the remote (or local) machine.
        try
        {
            scope.Connect();
        }
        catch (ManagementException ex)
        {
            // Failed to authenticate properly.
            jobOK = false;
            return "Failed to authenticate: " + ex.Message;
            //p_extendederror = (int)ex.ErrorCode;
            //return Status.AuthenticateFailure;
        }
        catch (System.Runtime.InteropServices.COMException)
        {
            // Unable to connect to the RPC service on the remote machine.
            jobOK = false;
            return "Unable to connect to RPC service";
            //p_extendederror = ex.ErrorCode;
            //return Status.RPCServicesUnavailable;
        }
        catch (System.UnauthorizedAccessException)
        {
            // User not authorized.
            jobOK = false;
            return "Error: Unauthorized access";
            //p_extendederror = 0;
            //return Status.UnauthorizedAccess;
        }

        try
        {
            ObjectQuery oq = new ObjectQuery(WMIQuery);
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, oq);

            foreach (ManagementObject queryObj in searcher.Get())
            {
                if (property != null)
                {
                    return queryObj[property];
                }
                else return queryObj;
            }
        }
        catch (Exception e)
        {
            jobOK = false;
            return "Error: " + e.Message;
        }
        return "";
    }
于 2015-10-14T08:36:05.487 回答
0

如果您启用了屏幕保护程序,我建议您检查屏幕保护程序进程中的 CreateDate 并与远程的 createdate 时间有所不同,您将获得空闲时间 + 屏幕保护程序超时

您可能想将 WMI 用于此类事情

它是一个黑客,但它有效

于 2013-07-21T11:02:37.150 回答