设置系统时间c#不工作
我想在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));
}
的MSDN说
如果函数成功,返回值是非零。如果功能 失败,则返回值为零。为了获得更多的错误信息, 调用GetLastError。
查看整个页面的http://msdn.microsoft.com/en-us/library/windows/desktop/ms724942%28v=vs.85%29.aspx。
您是否试图检查返回值,因此,最后一个错误?
下面是一个代码示例来获取返回值和一个错误代码: (只需更换自己的“SetSystemTime”呼叫)
var ret = SetSystemTime(ref systime);
Console.WriteLine("SetSystemTime return : " + ret);
System.Console.WriteLine("Last error : " + GetLastError());
不要忘记添加为进口GetLastError函数:
[DllImport("kernel32.dll")]
static extern uint GetLastError();
编辑:我刚刚试了一次,出现错误“ERROR_INVALID_PARAMETER 87(0x57)该参数不正确。”
所以,下面这个建议,我读过您的再次代码:
您写道:
systime.wHour = (ushort)d.Year;
代替:
systime.wYear = (ushort)d.Year;
固定,然后,没有更多的错误。
为了改变,你需要有以下权限的系统时间:SeSystemTimePrivilege
或者你可以运行你的应用程序作为管理员。以管理员身份登录的事实不会因为它与UAC相关而更改。您可以完全禁用UAC,但我不会推荐。
感谢您的回答!我修复了它。但是当我调用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