我想在Windows上的c#應用程序中設置Windows SystemTime。我已經實現了每個論壇(包括這裏)的例子,但它沒有迴應。 我有一個私人類有兩種方法:GetSystemTime()和SetSystemTime()。 GetSystemTime工作正常,但SetSystemTime沒有設置我嘗試從GetNetworkTime()傳遞的時間。 我做錯了什麼?我研究過,我不知道它是否是一個特權問題(我以管理員身份登錄,不應該這樣做),也可能是日期格式問題。設置系統時間c#不工作
問題是:當SetSystemTime()完成時,我應該看到系統時鐘的更改嗎?我怎麼知道它運行良好?因爲我沒有看到任何變化。 在這裏,我複製類和GetNetworkTime方法,它從NTP服務器獲取實際的小時。
public static class SystemTime
{
[DllImport("kernel32.dll", SetLastError = true)]
private extern static void GetSystemTime(ref SYSTEMTIME systime);
[DllImport("kernel32.dll", SetLastError = true)]
private extern static uint SetSystemTime(ref SYSTEMTIME systime);
private struct SYSTEMTIME
{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
private static void GetTime()
{
// Call the native GetSystemTime method
// with the defined structure.
SYSTEMTIME stime = new SYSTEMTIME();
GetSystemTime(ref stime);
}
public static void SetTime()
{
GetTime();
SYSTEMTIME systime = new SYSTEMTIME();
try
{
DateTime d = Intex.Core.Utils.Common.GetNetworkTime();
systime.wHour = (ushort)d.Year;
systime.wMonth = (ushort)d.Month;
systime.wDayOfWeek = (ushort)d.DayOfWeek;
systime.wDay = (ushort)d.Day;
systime.wHour = (ushort)d.Hour;
systime.wMinute = (ushort)d.Minute;
systime.wSecond = (ushort)d.Second;
systime.wMilliseconds = (ushort)d.Millisecond;
SetSystemTime(ref systime);
GetTime();
}
catch (Exception)
{
GetSystemTime(ref systime);
SetSystemTime(ref systime);
}
}
}
public static DateTime GetNetworkTime()
{
//default Windows time server
string ntpServer = ConfigurationManager.AppSettings["NTPServer"];
// NTP message size - 16 bytes of the digest (RFC 2030)
var ntpData = new byte[48];
//Setting the Leap Indicator, Version Number and Mode values
ntpData[0] = 0x1B; //LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)
var addresses = Dns.GetHostEntry(ntpServer).AddressList;
//The UDP port number assigned to NTP is 123
var ipEndPoint = new IPEndPoint(addresses[0], 123);
//NTP uses UDP
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Connect(ipEndPoint);
//Stops code hang if NTP is blocked
socket.ReceiveTimeout = 3000;
socket.Send(ntpData);
socket.Receive(ntpData);
socket.Close();
//Offset to get to the "Transmit Timestamp" field (time at which the reply
//departed the server for the client, in 64-bit timestamp format."
const byte serverReplyTime = 40;
//Get the seconds part
ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);
//Get the seconds fraction
ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);
//Convert From big-endian to little-endian
intPart = SwapEndianness(intPart);
fractPart = SwapEndianness(fractPart);
var milliseconds = (intPart * 1000) + ((fractPart * 1000)/0x100000000L);
//**UTC** time
var networkDateTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds((long)milliseconds);
return networkDateTime.ToLocalTime();
}
static uint SwapEndianness(ulong x)
{
return (uint)(((x & 0x000000ff) << 24) +
((x & 0x0000ff00) << 8) +
((x & 0x00ff0000) >> 8) +
((x & 0xff000000) >> 24));
}
感謝您的回答!我修復了它。但是當我調用Datetime.Now時,它不會更新,而且我仍然看到原始值。你知道爲什麼嗎? – user1545878 2014-10-08 14:28:26
除了你的回答,我有一個權限問題。我以管理員身份打開VS,它工作正常! – user1545878 2014-10-08 15:23:25
你看過GetLastError來找出它嗎?我想它也應該爲這類錯誤提供有用的信息;) – AFract 2014-10-08 17:17:42