c#调用win32 API函数修改系统时间

      一般来说,系统时间的修改可以通过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结构的指针,包含了新的本地日期和时间

SYSTEMTIME结构:

typedef struct _SYSTEMTIME {

WORD wYear;

WORD wMonth;

WORD wDayOfWeek;

WORD wDay;

WORD wHour;

WORD wMinute;

WORD wSecond;

WORD wMilliseconds;

} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;

     因此对应到C#语言中时,SetLocalTime函数声明形式应该为:public static extern bool SetLocalTime(ref SYSTEMTIME Time);

同时需要定义一个同样类型的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

你可能感兴趣的:(C#)