How do I set the Windows system clock to the correct local time using C#?
问题:
回答1:
You will need to P/Invoke the SetLocalTime
function from the Windows API. Declare it like this in C#:
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool SetLocalTime(ref SYSTEMTIME lpSystemTime);
[StructLayout(LayoutKind.Sequential)]
internal struct SYSTEMTIME
{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek; // ignored for the SetLocalTime function
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
To set the time, you simply initialize an instance of the SYSTEMTIME
structure with the appropriate values, and call the function. Sample code:
SYSTEMTIME time = new SYSTEMTIME();
time.wDay = 1;
time.wMonth = 5;
time.wYear = 2011;
time.wHour = 12;
time.wMinute = 15;
if (!SetLocalTime(ref time))
{
// The native function call failed, so throw an exception
throw new Win32Exception(Marshal.GetLastWin32Error());
}
However, note that the calling process must have the appropriate privileges in order to call this function. In Windows Vista and later, this means you will have to request process elevation.
Alternatively, you could use the SetSystemTime
function, which allows you to set the time in UTC (Coordinated Universal Time). The same SYSTEMTIME
structure is used, and the two functions are called in an identical fashion.
回答2:
.NET does not expose a function for that but you can use Win32 API SetSystemTime (in kernel32.dll) method. To get UTC time you should use an NTP Protocol Client and then adjust that time to the local time according to your regional settings.
public struct SYSTEMTIME
{
public ushort wYear,wMonth,wDayOfWeek,wDay,wHour,wMinute,wSecond,wMilliseconds;
}
[DllImport("kernel32.dll")]
public extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);
SYSTEMTIME systime = new SYSTEMTIME();
systime = ... // Set the UTC time here
SetSystemTime(ref systime);
回答3:
Here's a couple of articles on how to do that, complete with querying an atomic clock for the correct time.
http://www.codeproject.com/KB/IP/ntpclient.aspx
http://www.codeproject.com/KB/datetime/SNTPClient.aspx
回答4:
To get around the SE_SYSTEMTIME_NAME privilege issue, try creating a scheduled task to run your application and enable "Run with highest privileges."