使用c#从远程PC查找空闲时间

时间:2013-03-24 12:30:56

标签: c#

我需要使用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;
}

3 个答案:

答案 0 :(得分:1)

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

  

此功能对输入空闲检测很有用。然而,   GetLastInputInfo不提供系统范围的用户输入信息   跨所有正在运行的会话相反,GetLastInputInfo提供   仅针对会话的会话特定用户输入信息   调用了这个函数。

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

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

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

  

ITerminalServicesSession.LastInputTime

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

  

WTSQuerySessionInformation

答案 1 :(得分: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 "";
    }

答案 2 :(得分:0)

如果您启用了屏幕保护程序,我建议您检查屏幕保护程序上的CreateDate,并从遥控器中创建与创建时间的差异,并获得空闲时间+屏幕保护程序超时

您可能希望将WMI用于此类事情

它是一个黑客,但它的工作