0

C# アプリケーションを使用して、サーバー pc からリモート pc のアイドル時間を調べる必要があります。ローカル エリア ネットワークに接続されている IP アドレスとホスト名のリストがあります。LAN に接続された各コンピュータの 30 分以上のアイドル時間を調べたい。ローカル PC で実行しましたが、リモート PC では機能しません。これがローカルPC用の私のコードです。

[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 を使用します

WTSQuerySessionInformation

于 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 に答える