如何在c#中更改系统日期

时间:2013-07-08 16:07:23

标签: c# winapi date datetime time

我的程序需要能够更改机器上的SystemDate。环顾四周后,我找到了这个代码并实现了它,但它似乎根本没有改变日期。它运行的VM时间同步关闭,所以我知道问题不在那里。我犯了一个小错误,或者是否有更简单的方法来更改系统日期?

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

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



public bool SetSystemDateTime(DateTime newDateTime)
{
    bool result = false;

    try
    {
        newDateTime = newDateTime.ToUniversalTime();

        SYSTEMTIME sysTime = new SYSTEMTIME() 
            { wYear = (short)newDateTime.Year /* must be short */, 
            wMonth = (short)newDateTime.Month, 
            wDayOfWeek = (short)newDateTime.DayOfWeek, 
            wDay = (short)newDateTime.Day, 
            wHour = (short)newDateTime.Hour, 
            wMinute = (short)newDateTime.Minute, 
            wSecond = (short)newDateTime.Second, 
            wMilliseconds = (short)newDateTime.Millisecond };

        result = SetSystemTime(ref sysTime);
    }
    catch (Exception)
    {
        result = false;
    }
    return result;
}

2 个答案:

答案 0 :(得分:2)

以管理员身份运行此操作,因为它适用于我。代码来自SetSystemTime的{​​{3}}文档,虽然我在设置时间后添加了额外的Console.Read,以便可以在返回之前看到系统时间已更改原来的时间。

public struct SYSTEMTIME
{
   public ushort wYear, wMonth, wDayOfWeek, wDay,
          wHour, wMinute, wSecond, wMilliseconds;
}

[DllImport("kernel32.dll")]
public extern static void GetSystemTime(ref SYSTEMTIME lpSystemTime);

[DllImport("kernel32.dll")]
public extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);

Console.WriteLine(DateTime.Now.ToString());
SYSTEMTIME st = new SYSTEMTIME();
GetSystemTime(ref st);

Console.WriteLine("Adding 1 hour...");
st.wHour = (ushort)(st.wHour + 1 % 24);
if (SetSystemTime(ref st) == 0)
    Console.WriteLine("FAILURE: SetSystemTime failed");

Console.WriteLine(DateTime.Now.ToString());
Console.Read();

Console.WriteLine("Setting time back...");
st.wHour = (ushort)(st.wHour - 1 % 24);
SetSystemTime(ref st);
Console.WriteLine(DateTime.Now.ToString());
Console.WriteLine("Press Enter to exit");
Console.Read();

答案 1 :(得分:1)

  

该应用程序以管理员身份运行

现在这并不意味着很多用户使用管理员帐户登录Windows。重要的是您运行此代码提升。这需要a manifest具有“requireAdministrator”属性,以便用户获得UAC提升提示。

代码中的重大缺陷是容易忽略函数的返回值。也没有任何方法可以找出它返回false的原因。 [DllImport]存在缺陷,它不会将SetLastError属性设置为true。捕获异常而不生成诊断是一个坏主意,删除它。修正:

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetSystemTime(ref SYSTEMTIME lpSystemTime);
...
if (!SetSystemTime(ref sysTime)) {
   throw new System.ComponentModel.Win32Exception();
}