سؤال
ما هو أفضل وسيلة لضبط الوقت على جهاز بعيد عن بعد؟ هو الجهاز بنظام التشغيل Windows XP ويتم تلقي الوقت الجديد من خلال مكالمة خدمة ويب. والهدف هو الحفاظ على الأجهزة البعيدة في التوافق مع الخادم. يتم تأمين النظام باستمرار بحيث خدمة الويب لدينا هو المنفذ الوحيد، لذلك لا يمكن استخدام ملقم وقت على كل جهاز عن بعد.
المحلول
وأود أن استخدام ويندوز المدمج في قدرات وقت الإنترنت. يمكنك إنشاء خادم الوقت على الخادم الخاص بك، يكون ذلك الحصول على الوقت من الدرجة 2ND الانتهازي، ويكون كل الأجهزة العميلة الخاصة بك الحصول على الوقت من ذلك.
ولقد كنت على الطريق إعداد تطبيق نظام الوقت من قبل.
نصائح أخرى
وهذه هي دعوة API Win32 ولتحديد الوقت النظام:
[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 );
ولست متأكدا بالضبط كيف ستحصل عملت الأمن خارج بحيث يمكن تنفيذ هذه المهمة على العميل، على الرغم من.
ويمكنك الحصول على الكثير من التفاصيل بشأن تحديد وقت النظام على PInvoke أ >.
والطريق إلى الاستعلام عن الجهاز شبكة لانها وقت النظام هو <وأ href = "http://msdn.microsoft.com/en-us/library/aa370612(VS.85).aspx" يختلط = "نوفولو noreferrer "> NetRemoteTOD .
وهنا كود للقيام بذلك في دلفي (يتم نشر سبيل المثال استخدام أدناه).
ومنذ ذلك يعتمد على المكالمات API ويندوز، وأنه لا ينبغي أن تكون مختلفة جدا في 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;
وهنا هو المثال الاستعمال:
procedure TfrmMain.SynchLocalTimeWithServer;
var
tod : TTimeHandler;
begin
tod := TTimeHandler.Create(cboServerName.Text);
try
tod.SetLocalSystemTime(tod.RemoteSystemTime);
finally
FreeAndNil(tod);
end; //try-finally
end;
إليك الروتين لقد تم استخدام لسنوات لقراءة قيمة DateTime
قبالة SQL خادم لدينا لدينا (باستخدام وقت ملف)، وتحويله إلى SYSTEMTIME
التي تم تعيينها على جهاز الكمبيوتر.
وهذا يعمل على أجهزة الكمبيوتر الشخصية وأجهزة ويندوز موبايل.
ويمكن أن يطلق عليه في أي وقت كنت يحدث ليكون داعيا لديك 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;
}
}
وربما يمكن أن أيضا القيام بذلك في ملف دفعي باستخدام مزيج من بعض
TIME
ولضبط الوقت، و
net time \\server_name
ولاسترداد الوقت من خادم.