我正在尝试使用以下内容更新系统时间:
[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)时,它会给我新的更新时间。有人可以给我一些帮助吗?
答案 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
类来获取和更改日期或时间。属性Today
和TimeOfDay
具有将对日期或时间进行更改的设置器。
您仍需要相关权限 - 请参阅下面的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)
你只有一个权限问题,当我没有权限运行该程序时,它不会更改日期,但如果我右键单击该程序,然后单击以管理员身份运行,它就可以运行!