• C# 同步更新系统时间


    前言

    在定位用户问题时,发现有些电脑,会出现系统时间不是最新的问题。

    可能原因:

    1. 取消了勾选服务器时间同步
    2. 当前安装的系统,是一个未知来源系统,导致系统时间更新失败

    而系统时间不正确,会导致IE选项-证书,校验不通过~

    更新系统时间

    1. 连接时间服务器

    时间服务器列表(推荐): string[] timeHosts = { "time.windows.com", "time.nist.gov" };

     1     /// <summary>
     2     /// 连接时间服务器
     3     /// </summary>
     4     /// <param name="socket">服务器接口</param>
     5     /// <param name="startTime">开始时间</param>
     6     /// <param name="errorMsg">错误信息</param>
     7     /// <returns></returns>
     8     private static bool TryConnectToTimeServer(out Socket socket, out DateTime startTime, out string errorMsg)
     9     {
    10         socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建Socket   
    11         socket.ReceiveTimeout = 10 * 1000;//设置超时时间   
    12         errorMsg = string.Empty;
    13         startTime = DateTime.Now;
    14 
    15         // 遍历时间服务器列表   
    16         foreach (string strHost in timeHosts)
    17         {
    18             try
    19             {
    20                 // 记录开始的时间   
    21                 startTime = DateTime.Now;
    22 
    23                 var iphostinfo = Dns.GetHostEntry(strHost);
    24                 var ip = iphostinfo.AddressList[0];
    25                 //建立IPAddress对象与端口,创建IPEndPoint节点:   
    26                 int port = 13;
    27                 var ipe = new IPEndPoint(ip, port);
    28                 //连接到服务器   
    29                 socket.Connect(ipe);
    30                 // 如果连接到服务器就跳出  
    31                 if (socket.Connected) break;
    32             }
    33             catch (Exception ex)
    34             {
    35                 errorMsg = $"时间服务器连接失败!
    错误信息:{ex.Message}系统提示";
    36             }
    37         }
    38         return socket.Connected;
    39     }

    2. 从服务器接收数据

     1     /// <summary>
     2     /// 从服务器接收数据
     3     /// </summary>
     4     /// <param name="socket"></param>
     5     /// <returns></returns>
     6     private static StringBuilder ReceiveMessageFromServer(Socket socket)
     7     {
     8         //SOCKET同步接受数据   
     9         byte[] receiveBytes = new byte[1024];
    10         int nBytes, nTotalBytes = 0;
    11         StringBuilder sb = new StringBuilder();
    12         System.Text.Encoding encoding = Encoding.UTF8;
    13 
    14         while ((nBytes = socket.Receive(receiveBytes, 0, 1024, SocketFlags.None)) > 0)
    15         {
    16             nTotalBytes += nBytes;
    17             sb.Append(encoding.GetString(receiveBytes, 0, nBytes));
    18         }
    19 
    20         return sb;
    21     }

    3. 更新本地时间

     1     /// <summary>
     2     /// 更新系统时间
     3     /// </summary>
     4     /// <returns>更新结果</returns>
     5     public static string UpdateSystemTime()
     6     {
     7         try
     8         {
     9             var connected = TryConnectToTimeServer(out Socket socket, out var startTime, out string errorMsg);
    10             if (connected)
    11             {
    12                 var receivedMsg = ReceiveMessageFromServer(socket);
    13                 socket.Close();
    14                 //切割字符串 
    15                 string[] receiveMsgList = receivedMsg.ToString().Split(' ');
    16                 if (receiveMsgList.Length >= 3)
    17                 {
    18                     var dateTimeValue = receiveMsgList[1] + " " + receiveMsgList[2];
    19                     SetLocalTime(startTime, dateTimeValue);
    20                 }
    21             }
    22             else
    23             {
    24                 return errorMsg;
    25             }
    26         }
    27         catch (Exception e)
    28         {
    29             return $"函数{nameof(UpdateSystemTime)}执行异常,{e.Message}";
    30         }
    31         return "时间已同步";
    32     }
    33     /// <summary>
    34     /// 设置系统时间
    35     /// </summary>
    36     /// <param name="startTime">请求服务器时的开始时间</param>
    37     /// <param name="dateTimeValue">服务器返回的时间</param>
    38     private static void SetLocalTime(DateTime startTime, string dateTimeValue)
    39     {
    40         // 得到开始到现在所消耗的时间 
    41         TimeSpan k = DateTime.Now - startTime;
    42         // 减去中途消耗的时间
    43         DateTime updatedUtcTime = Convert.ToDateTime(dateTimeValue).Subtract(-k);
    44 
    45         //处置北京时间 +8时   
    46         var updatedTime = updatedUtcTime.AddHours(8);
    47 
    48         //转换System.DateTime到SystemTime   
    49         SystemTime systemTime = new SystemTime();
    50         systemTime.FromDateTime(updatedTime);
    51 
    52         //调用Win32 API设置系统时间   
    53         Win32API.SetLocalTime(ref systemTime);
    54     }

    系统时间辅助类 & Win32API :

     1     /// <summary>
     2     /// 系统时间帮助类
     3     /// </summary>
     4     public struct SystemTime
     5     {
     6         public ushort wYear;
     7         public ushort wMonth;
     8         public ushort wDayOfWeek;
     9         public ushort wDay;
    10         public ushort wHour;
    11         public ushort wMinute;
    12         public ushort wSecond;
    13         public ushort wMilliseconds;
    14 
    15         /// <summary>
    16         /// 从System.DateTime转换。
    17         /// </summary>
    18         /// <param name="time">System.DateTime类型的时间。</param>
    19         public void FromDateTime(DateTime time)
    20         {
    21             wYear = (ushort)time.Year;
    22             wMonth = (ushort)time.Month;
    23             wDayOfWeek = (ushort)time.DayOfWeek;
    24             wDay = (ushort)time.Day;
    25             wHour = (ushort)time.Hour;
    26             wMinute = (ushort)time.Minute;
    27             wSecond = (ushort)time.Second;
    28             wMilliseconds = (ushort)time.Millisecond;
    29         }
    30         /// <summary>
    31         /// 转换为System.DateTime类型。
    32         /// </summary>
    33         /// <returns></returns>
    34         public DateTime ToDateTime()
    35         {
    36             return new DateTime(wYear, wMonth, wDay, wHour, wMinute, wSecond, wMilliseconds);
    37         }
    38         /// <summary>
    39         /// 静态方法。转换为System.DateTime类型。
    40         /// </summary>
    41         /// <param name="time">SYSTEMTIME类型的时间。</param>
    42         /// <returns></returns>
    43         public static DateTime ToDateTime(SystemTime time)
    44         {
    45             return time.ToDateTime();
    46         }
    47     }
    48 
    49     /// <summary>
    50     /// 系统更新时间DLL
    51     /// </summary>
    52     public class Win32API
    53     {
    54         [DllImport("Kernel32.dll")]
    55         public static extern bool SetLocalTime(ref SystemTime Time);
    56         [DllImport("Kernel32.dll")]
    57         public static extern void GetLocalTime(ref SystemTime Time);
    58     }
    View Code

    Github地址:IE环境修复工具

  • 相关阅读:
    Qt通用方法及类库9
    设计模式原则(7)--Composition&AggregationPrinciple(CARP)--合成&聚合复用原则
    设计模式原则(6)--Open-Closed Principle(OCP)--开闭原则
    鼠标悬停出现页面
    设计模式(23)--Visitor--访问者模式--行为型
    设计模式(22)--Template Method(模板方法模式)--行为型
    设计模式(21)--Strategy(策略模式)--行为型
    设计模式(20)--State(状态模式)--行为型
    设计模式(19)--Observer(观察者模式)--行为型
    设计模式(18)--Memento(备忘录模式)--行为型
  • 原文地址:https://www.cnblogs.com/kybs0/p/10953934.html
Copyright © 2020-2023  润新知