一般来说,系统时间的修改可以通过win32 API函数库中的SetLocalTime函数进行设置。对于C#语言来说,虽然win32 API大部分函数都已经封装在了.NET Framework类库中,但C#中时间日期的封装类System.DateTime却没有操作修改系统时间的成员,因此我们仍然需要调用win23 API的SetLocalTime函数。
那么问题来了,面向对象的C#语言该如何调用C语言的API函数?
我们知道API函数是存在于.dll文件中,对于.NET平台上的C#语言,只需要通过DllImport特性即可调用API函数。主要过程如下:
(1) 要使用DllImport特性,必须包含命名空间:System.Runtime.InteropServices
(2) 创建DllImport特性类的实例
— 特性类实例的创建形式为:[特性类(参数列表)]
— 上述参数是指需要调用的API函数所在的dll文件(可以在MSDN中查询API函数位于哪个dll文件)
(3) 调用win32 API函数
— 函数返回值及参数类型与win32 API对应的函数一致(这步需要确定win32数据类型所对应的.NET平台数据类型)
— 函数还需要额外增加public static extern进行声明
下面开始进入正题吧,调用win32 API中的SetLocalTime函数修改系统时间:
代码部分参考自博客:http://www.cnblogs.com/zty1294625258/p/6084672.html
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices; //(1)
namespace ConsoleApplication1
{
//创建一个SYSTEMTIME结构
public 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;
//利用System.DateTime设置SYSTEMTIME数据成员
public void FromDateTime(DateTime time)
{
wYear = (ushort)time.Year;
wMonth = (ushort)time.Month;
wDayOfWeek = (ushort)time.DayOfWeek;
wDay = (ushort)time.Day;
wHour = (ushort)time.Hour;
wMinute = (ushort)time.Minute;
wSecond = (ushort)time.Second;
wMilliseconds = (ushort)time.Millisecond;
}
}
public class Win32API
{
[DllImport("Kernel32.dll")] //(2)
public static extern bool SetLocalTime(ref SYSTEMTIME Time); //(3)
[DllImport("Kernel32.dll")]
public static extern void GetLocalTime(ref SYSTEMTIME Time);
}
class Program
{
static void Main(string[] args)
{
SYSTEMTIME MySystemTime = new SYSTEMTIME();
Win32API.GetLocalTime(ref MySystemTime);
MySystemTime.FromDateTime(DateTime.Now.AddHours(2)); //在当前时间上加上两个小时
Console.WriteLine("修改之前的当前系统时间:{0}", DateTime.Now.ToString());
Win32API.SetLocalTime(ref MySystemTime);
Console.WriteLine("修改之后的当前系统时间:{0}", DateTime.Now.ToString());
Console.ReadKey();
}
}
}
(1)命名空间不用解释了
(2)创建DllImport实例时,查询得到SetLocalTime函数所在的dll文件为"Kernel32.dll"
(3)声明调用API函数时,首先要知道SetLocalTime函数在win32 API中的形式为:
BOOL WINAPI SetLocalTime( _In_ constSYSTEMTIME *lpSystemTime);
— 参数: lpSystemTime 一个SYSTEMTIME结构的指针,包含了新的本地日期和时间
因此对应到C#语言中时,SetLocalTime函数声明形式应该为:public static extern bool SetLocalTime(ref SYSTEMTIME Time);SYSTEMTIME结构:
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
同时需要定义一个同样类型的SYSTEMTIME 结构体。
最后关于程序的运行,对于win7系统以上,SetLocalTime函数需要获取SE_SYSTEMTIME_NAME权限,所以在运行时需要右键以管理员身份运行,才能修改成功。
关于在代码中直接获取权限修改时间的教程参考社区论坛:https://social.msdn.microsoft.com/Forums/zh-CN/fd806d68-a895-4df6-b7f2-3c158357952e/-win10-datetimenowtostring-0318-224209-?forum=2212&forum=2212