Reputation: 38694
Is there any class available to get a remote PC's date time in .net? In order to do it, I can use a computer name or time zone. For each case, are there different ways to get the current date time? I am using Visual Studio 2005.
Upvotes: 4
Views: 16695
Reputation: 2171
You can use pinvoke to NetRemoteTOD native API. Here is a small PoC.
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
struct TIME_OF_DAY_INFO
{
public uint elapsedt;
public int msecs;
public int hours;
public int mins;
public int secs;
public int hunds;
public int timezone;
public int tinterval;
public int day;
public int month;
public int year;
public int weekday;
}
class Program
{
[DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
private static extern int NetRemoteTOD(string uncServerName, out IntPtr buffer);
[DllImport("netapi32.dll")]
private static extern void NetApiBufferFree(IntPtr buffer);
internal static DateTimeOffset GetServerTime(string serverName = null)
{
if (serverName != null && !serverName.StartsWith(@"\\"))
{
serverName = @"\\" + serverName;
}
int rc = NetRemoteTOD(serverName, out IntPtr buffer);
if (rc != 0)
{
throw new Win32Exception(rc);
}
try
{
var tod = Marshal.PtrToStructure<TIME_OF_DAY_INFO>(buffer);
return DateTimeOffset.FromUnixTimeSeconds(tod.elapsedt).ToOffset(TimeSpan.FromMinutes(-tod.timezone));
}
finally
{
NetApiBufferFree(buffer);
}
}
static void Main(string[] args)
{
Console.WriteLine(DateTimeOffset.Now);
Console.WriteLine(GetServerTime());
Console.WriteLine(GetServerTime("host1"));
Console.WriteLine(GetServerTime("host2.domain.tld"));
Console.ReadLine();
}
}
Upvotes: 0
Reputation: 5506
Since WMI code would be very slow, you can use the below code to get faster results
string machineName = "vista-pc";
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.FileName = "net";
proc.StartInfo.Arguments = @"time \\" + machineName;
proc.Start();
proc.WaitForExit();
List<string> results = new List<string>();
while (!proc.StandardOutput.EndOfStream)
{
string currentline = proc.StandardOutput.ReadLine();
if (!string.IsNullOrEmpty(currentline))
{
results.Add(currentline);
}
}
string currentTime = string.Empty;
if (results.Count > 0 && results[0].ToLower().StartsWith(@"current time at \\" + machineName.ToLower() + " is "))
{
currentTime = results[0].Substring((@"current time at \\" + machineName.ToLower() + " is ").Length);
Console.WriteLine(DateTime.Parse(currentTime));
Console.ReadLine();
}
Upvotes: 3
Reputation: 942267
You can use remote WMI and the Win32_TimeZone
class. You do need to have permission to execute WMI queries on that machine. Avoid hassle like this by working with UTC instead of local time.
Upvotes: 1
Reputation: 9422
On a Windows machine there is net time \\<remote-ip address>
to get the time of a remote machine. You could use that to find the remote system time, if you want code you can wrap it up in the function to execute the shell (DOS) functions in C#.
Upvotes: 1
Reputation: 1072
I give you a solution which uses WMI. You may or may not need the domain and security information:
try
{
string pc = "pcname";
//string domain = "yourdomain";
//ConnectionOptions connection = new ConnectionOptions();
//connection.Username = some username;
//connection.Password = somepassword;
//connection.Authority = "ntlmdomain:" + domain;
string wmipath = string.Format("\\\\{0}\\root\\CIMV2", pc);
//ManagementScope scope = new ManagementScope(
// string.Format("\\\\{0}\\root\\CIMV2", pc), connection);
ManagementScope scope = new ManagementScope(wmipath);
scope.Connect();
ObjectQuery query = new ObjectQuery(
"SELECT * FROM Win32_LocalTime");
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(scope, query);
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Win32_LocalTime instance");
Console.WriteLine("-----------------------------------");
Console.WriteLine("Date: {0}-{1}-{2}", queryObj["Year"], queryObj["Month"], queryObj["Day"]);
Console.WriteLine("Time: {0}:{1}:{2}", queryObj["Hour"], queryObj["Minute"], queryObj["Second"]);
}
}
catch (ManagementException err)
{
Console.WriteLine("An error occurred while querying for WMI data: " + err.Message);
}
catch (System.UnauthorizedAccessException unauthorizedErr)
{
Console.WriteLine("Connection error (user name or password might be incorrect): " + unauthorizedErr.Message);
}
Upvotes: 6