Set the time programmatically using C #

What is the best way to remotely set the time on a remote computer? The device runs on Windows XP and receives new time through a call to a web service. The goal is to synchronize remote computers with the server. The system is locked, so our web service is the only access, so I can not use the time server on each remote computer.

+7
c # time
source share
5 answers

I would use the capabilities of Windows built-in Internet time. You can configure the time server on your server, get the time from the second time server and get all your client machines. From him.

I used to work with the application configuration system.

+5
source share

This is the Win32 API call to set the system time:

[StructLayout(LayoutKind.Sequential)] public struct SYSTEMTIME { public short wYear; public short wMonth; public short wDayOfWeek; public short wDay; public short wHour; public short wMinute; public short wSecond; public short wMilliseconds; } [DllImport("kernel32.dll", SetLastError=true)] public static extern bool SetSystemTime(ref SYSTEMTIME theDateTime ); 

I'm not quite sure how you will get security designed so that you can perform this function on the client.

You can get more detailed information about setting the system time on PInvoke .

+8
source share

A method for querying a network device for its system time is NetRemoteTOD .

Here's the code for this in Delphi (a usage example is posted below).

Since it uses Windows API calls, it should not be too different in C #.

 unit TimeHandler; interface type TTimeHandler = class private FServerName : widestring; public constructor Create(servername : widestring); function RemoteSystemTime : TDateTime; procedure SetLocalSystemTime(settotime : TDateTime); end; implementation uses Windows, SysUtils, Messages; function NetRemoteTOD(ServerName :PWideChar; var buffer :pointer) : integer; stdcall; external 'netapi32.dll'; function NetApiBufferFree(buffer : Pointer) : integer; stdcall; external 'netapi32.dll'; type //See MSDN documentation on the TIME_OF_DAY_INFO structure. PTime_Of_Day_Info = ^TTime_Of_Day_Info; TTime_Of_Day_Info = record ElapsedDate : integer; Milliseconds : integer; Hours : integer; Minutes : integer; Seconds : integer; HundredthsOfSeconds : integer; TimeZone : LongInt; TimeInterval : integer; Day : integer; Month : integer; Year : integer; DayOfWeek : integer; end; constructor TTimeHandler.Create(servername: widestring); begin inherited Create; FServerName := servername; end; function TTimeHandler.RemoteSystemTime: TDateTime; var Buffer : pointer; Rek : PTime_Of_Day_Info; DateOnly, TimeOnly : TDateTime; timezone : integer; begin //if the call is successful... if 0 = NetRemoteTOD(PWideChar(FServerName),Buffer) then begin //store the time of day info in our special buffer structure Rek := PTime_Of_Day_Info(Buffer); //windows time is in GMT, so we adjust for our current time zone if Rek.TimeZone <> -1 then timezone := Rek.TimeZone div 60 else timezone := 0; //decode the date from integers into TDateTimes //assume zero milliseconds try DateOnly := EncodeDate(Rek.Year,Rek.Month,Rek.Day); TimeOnly := EncodeTime(Rek.Hours,Rek.Minutes,Rek.Seconds,0); except on e : exception do raise Exception.Create( 'Date retrieved from server, but it was invalid!' + #13#10 + e.Message ); end; //translate the time into a TDateTime //apply any time zone adjustment and return the result Result := DateOnly + TimeOnly - (timezone / 24); end //if call was successful else begin raise Exception.Create('Time retrieval failed from "'+FServerName+'"'); end; //free the data structure we created NetApiBufferFree(Buffer); end; procedure TTimeHandler.SetLocalSystemTime(settotime: TDateTime); var SystemTime : TSystemTime; begin DateTimeToSystemTime(settotime,SystemTime); SetLocalTime(SystemTime); //tell windows that the time changed PostMessage(HWND_BROADCAST,WM_TIMECHANGE,0,0); end; 

And here is a usage example:

 procedure TfrmMain.SynchLocalTimeWithServer; var tod : TTimeHandler; begin tod := TTimeHandler.Create(cboServerName.Text); try tod.SetLocalSystemTime(tod.RemoteSystemTime); finally FreeAndNil(tod); end; //try-finally end; 
+3
source share

In this program, which I have used for many years to read the DateTime value of our SQL Server (using file time), convert it to SYSTEMTIME , which is installed on the PC.

This works for PCs and Windows Mobile devices.

It can be called at any time when you call your SQL Server.

 public class TimeTool { private static readonly DateTime NODATE = new DateTime(1900, 1, 1); #if PocketPC [DllImport("coredll.dll")] #else [DllImport("kernel32.dll")] #endif static extern bool SetLocalTime([In] ref SYSTEMTIME lpLocalTime); public struct SYSTEMTIME { public short Year, Month, DayOfWeek, Day, Hour, Minute, Second, Millisecond; /// <summary> /// Convert form System.DateTime /// </summary> /// <param name="time">Creates System Time from this variable</param> public void FromDateTime(DateTime time) { Year = (short)time.Year; Month = (short)time.Month; DayOfWeek = (short)time.DayOfWeek; Day = (short)time.Day; Hour = (short)time.Hour; Minute = (short)time.Minute; Second = (short)time.Second; Millisecond = (short)time.Millisecond; } public DateTime ToDateTime() { return new DateTime(Year, Month, Day, Hour, Minute, Second, Millisecond); } public static DateTime ToDateTime(SYSTEMTIME time) { return time.ToDateTime(); } } // read SQL Time and set time on device public static int SyncWithSqlTime(System.Data.SqlClient.SqlConnection con) { SYSTEMTIME systemTime = new SYSTEMTIME(); DateTime sqlTime = NODATE; string sql = "SELECT GETDATE() AS [CurrentDateTime]"; using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(sql, con)) { try { cmd.Connection.Open(); System.Data.SqlClient.SqlDataReader r = cmd.ExecuteReader(); while (r.Read()) { if (!r.IsDBNull(0)) { sqlTime = (DateTime)r[0]; } } } catch (Exception) { return -1; } } if (sqlTime != NODATE) { systemTime.FromDateTime(sqlTime); // Convert to SYSTEMTIME if (SetLocalTime(ref systemTime)) { //Call Win32 API to set time return 1; } } return 0; } } 
+1
source share

Perhaps you can also do this in a batch file using some combination

 TIME 

to set the time, and

 net time \\server_name 

to get time from the server.

0
source share

All Articles