如何使用.NET更新系统的日期和/或时间

时间:2009-02-06 19:43:14

标签: c# .net vb.net

我正在尝试使用以下内容更新系统时间:

[StructLayout(LayoutKind.Sequential)] 
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;
}

[DllImport("kernel32.dll", EntryPoint = "GetSystemTime", SetLastError = true)]
private extern static void Win32GetSystemTime(ref SYSTEMTIME lpSystemTime);

[DllImport("kernel32.dll", EntryPoint = "SetSystemTime", SetLastError = true)]
private extern static bool Win32SetSystemTime(ref SYSTEMTIME lpSystemTime);

public void SetTime()
{
    TimeSystem correctTime = new TimeSystem();
    DateTime sysTime = correctTime.GetSystemTime();
    // Call the native GetSystemTime method
    // with the defined structure.
    SYSTEMTIME systime = new SYSTEMTIME();
    Win32GetSystemTime(ref systime);

    // Set the system clock ahead one hour. 
    systime.wYear = (ushort)sysTime.Year;
    systime.wMonth = (ushort)sysTime.Month;
    systime.wDayOfWeek = (ushort)sysTime.DayOfWeek;
    systime.wDay = (ushort)sysTime.Day;
    systime.wHour = (ushort)sysTime.Hour;
    systime.wMinute = (ushort)sysTime.Minute;
    systime.wSecond = (ushort)sysTime.Second;
    systime.wMilliseconds = (ushort)sysTime.Millisecond;

    Win32SetSystemTime(ref systime);
}

当我调试一切看起来很好并且所有值都是正确的但是当它调用Win32SetSystemTime(ref systime)时,系统的实际时间(显示时间)不会改变并保持不变。奇怪的是,当我调用Win32GetSystemTime(ref systime)时,它会给我新的更新时间。有人可以给我一些帮助吗?

7 个答案:

答案 0 :(得分:6)

您的部分问题是您有一些不正确的PInvoke签名。最值得注意的SetSystemTime应具有非void返回值。这是正确的签名

    /// Return Type: BOOL->int
    ///lpSystemTime: SYSTEMTIME*
    [System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="SetSystemTime")]
    [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
public static extern  bool SetSystemTime([InAttribute()] ref SYSTEMTIME lpSystemTime) ;

我怀疑返回值的锁定搞砸了堆栈,而SetSystemTime函数基本上是以坏数据结束的。

答案 1 :(得分:4)

根据您所拥有的代码,您不会增加小时数。看起来您将系统时间设置为与调用Win32GetSystemTime时完全相同的时间。

尝试:

systime.wHour = (ushort)(sysTime.Hour + 1);

答案 2 :(得分:2)


TimeSpan diffLocalTime = DateTime.Now - DateTime.UtcNow; 
SystemTime systemTime = new SystemTime(); 
systemTime.Second = ... 
systemTime.Minute =.... 
systemTime.Hour -= (ushort)(diffLocalTime.Hours + 1); // 00:59:59 I rounded as 1 hour 
bool result = SetSystemTime(ref systemTime); 

这使用它在本地时区正常工作。

答案 3 :(得分:2)

不需要P / Invoke - Microsoft.VisualBasic程序集中提供了一种更简单的方法(但并不为人所熟知)。如果您使用的是C#,请记住添加对它的引用。

您可以使用Microsoft.VisualBasic.DateAndTime类来获取和更改日期或时间。属性TodayTimeOfDay具有将对日期或时间进行更改的设置器。

您仍需要相关权限 - 请参阅下面的MSDN文档链接。

这是一个改变时间的任意例子:

public static void SetTimeToPast()
{
    Microsoft.VisualBasic.DateAndTime.TimeOfDay = DateTime.Now.AddMinutes( -2 );
}

MSDN参考:http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.dateandtime(v=vs.110).aspx

答案 4 :(得分:1)

问题是关于UTC时间和当地时间。 看到这个链接: http://www.codeproject.com/Messages/2998246/problem-with-SetSystemTime-fucntion-of-Kernel32-dl.aspx

希望这对你有帮助。

答案 5 :(得分:1)

 [DllImport("Kernel32.dll")]
 public static extern bool SetLocalTime(ref StractData.Datetime.SYSTEMTIME Time);

答案 6 :(得分:0)

你只有一个权限问题,当我没有权限运行该程序时,它不会更改日期,但如果我右键单击该程序,然后单击以管理员身份运行,它就可以运行!