1

我一直在寻找如何获取远程 PC 的 System.Environment.TickCount。使用这个简单的代码从我的本地 PC 获取我想要的信息,但我不知道如何为我们域网络中的每台 PC 获取相同的信息。我想从我们的服务器上运行它。

TimeSpan t = TimeSpan.FromMilliseconds(System.Environment.TickCount);
MessageBox.Show(t.Days.ToString() + "days, " + t.Hours.ToString() + "hrs & " + t.Minutes.ToString() + "mins.");

我有这个代码来获取网络中的所有计算机名称:

public List<String> ListNetworkComputers()
{
    List<String> _ComputerNames = new List<String>();
    String _ComputerSchema = "Computer";
    System.DirectoryServices.DirectoryEntry _WinNTDirectoryEntries = new System.DirectoryServices.DirectoryEntry("WinNT:");
    foreach (System.DirectoryServices.DirectoryEntry _AvailDomains in _WinNTDirectoryEntries.Children)
    {
        foreach (System.DirectoryServices.DirectoryEntry _PCNameEntry in _AvailDomains.Children)
        {
            if (_PCNameEntry.SchemaClassName.ToLower().Contains(_ComputerSchema.ToLower()))
            {
                _ComputerNames.Add(_PCNameEntry.Name);
            }
        }
    }
    return _ComputerNames;
}

如何使用此信息从每台 PC 获取 System.Environment.TickCount?我已经尝试过 PsExec.exe,但我真的不知道如何让它为我工作。我试过这个但它不起作用:

var list = ListNetworkComputers();
foreach (var pc in list)
{
    string output = "";
    using (var process = new System.Diagnostics.Process())
    {
        process.StartInfo.FileName = @"C:\PsExec.exe";
        process.StartInfo.Arguments = @"\\" + pc + " cmd /c echo " + "System.Environment.TickCount";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.RedirectStandardOutput = true;
        process.Start();
        output = process.StandardOutput.ReadToEnd();
    }
    int count = 0;
    Int32.TryParse(output, out count);
    TimeSpan ts = TimeSpan.FromMilliseconds(count);
    MessageBox.Show(pc + ": " + ts.Days.ToString() + "days, " + ts.Hours.ToString() + "hrs & " + ts.Minutes.ToString() + "mins.");
}
4

2 回答 2

0

而不是使用“cmd.exe”,也许你可以使用 PowerShell?如果是这样,打印该属性是一个简单的命令:[System.Environment]::TickCount

于 2014-03-27T02:22:21.993 回答
0

我需要做同样的事情:获取远程 PC 的 System.Environment.TickCount

我想出了这个解决方案(使用Windows Management Instrumentation或 WMI LocalDateTime - LastBootUpTime),但与Environment.TickCount(参见下面的代码注释)相比,它并不是 100% 准确的。

所以我在网上查了其他解决方案。原来@HansPassant 提出了同样的建议。对于我的用例,+/-100 滴答的差异应该无关紧要。

using Microsoft.Management.Infrastructure;
using Microsoft.Management.Infrastructure.Options;
using System;
using System.Linq;
using System.Security;

namespace TickCountTest
{
    class Program
    {
        /// <summary>
        /// Print the system TickCount (converted from Win32_OperatingSystem LocalDateTime - LastBootUpTime properties).
        /// Why? Because this technique can be used to get TickCount from a Remote machine.
        /// </summary>
        public static void Main(string[] args)
        {
            var tickCount = GetRemoteMachineTickCount("REMOTEMACHINENAME");

            if (!tickCount.HasValue)
            {
                throw new NullReferenceException("GetRemoteMachineTickCount() response was null.");
            }

            Console.WriteLine($"TickCount: {tickCount}");
            Console.ReadKey();
        }

        /// <summary>
        /// Retrieves the duration (TickCount) since the system was last started from a remote machine.
        /// </summary>
        /// <param name="computerName">Name of computer on network to retrieve tickcount for</param>
        /// <returns>WMI Win32_OperatingSystem LocalDateTime - LastBootUpTime (ticks)</returns>
        private static int? GetRemoteMachineTickCount(string computerName)
        {
            string namespaceName = @"root\cimv2";
            string queryDialect = "WQL";

            DComSessionOptions SessionOptions = new DComSessionOptions();
            SessionOptions.Impersonation = ImpersonationType.Impersonate;

            var baseLineTickCount = Environment.TickCount; // Note: to determine discrepancy
            CimSession session = CimSession.Create(computerName, SessionOptions);

            string query = "SELECT * FROM Win32_OperatingSystem";
            var cimInstances = session.QueryInstances(namespaceName, queryDialect, query);

            if (cimInstances.Any())
            {
                var cimInstance = cimInstances.First();
                var lastBootUpTime = Convert.ToDateTime(cimInstance.CimInstanceProperties["LastBootUpTime"].Value);
                var localDateTime = Convert.ToDateTime(cimInstance.CimInstanceProperties["LocalDateTime"].Value);

                var timeSpan = localDateTime - lastBootUpTime;
                var tickCount = Convert.ToInt32(timeSpan.TotalMilliseconds);

                var discrepancy = tickCount - baseLineTickCount; // Note: discrepancy about +/- 100 ticks

                return tickCount;
            }

            return null;
        }
    }
}
于 2019-11-07T00:18:49.163 回答