我一直在寻找如何获取远程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.");
}
代替使用“ cmd.exe”,也许可以使用PowerShell?如果是这样,这是打印该属性的简单命令:[System.Environment]::TickCount
我需要做同样的事情:获取远程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;
}
}
}