• C#如何获取和设置客户端电脑的系统时间?
  • 发布于 2个月前
  • 389 热度
    0 评论
在日常工作中,有时可能会需要获取或修改客户端电脑的系统时间,比如软件设置了Licence有效期,预计2024-06-01 00:00:00到期,如果客户手动修改了客户端电脑时间,往前调整了一年,则软件就可以继续使用一年,如此循环往复,则Licence将形同虚设。所以有时候需要校验客户端电脑时间和服务器端时间,是否一致,如果不一致,则需要修改客户端电脑时间或进行系统提示。本文以一个简单的小例子,简述如果通过C#获取和设置客户端电脑的系统时间,仅供学习分享使用,如有不足之处,还请指正。

涉及知识点
在windows系统中,设置系统时间,主要通过win32提供的API来实现,如下所示:
SetLocalTime 设置系统的本地化时间
GetLocalTime 获取系统的本地化时间
SetSystemTime 设置系统的Utc时间
GetSystemTime 获取系统的Utc时间

核心代码
1. 时间结构体
在上述四个系统函数中,都需要一个时间类型的结构体作为参数,包含时分秒,年月日。如下所示:
[StructLayout(LayoutKind.Sequential)]
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;
 
  public override string ToString()
  {
    return $"{wYear}-{wMonth}-{wDay} {wHour}:{wMinute}:{wSecond}.{wMilliseconds}";
  }
}
2. 系统时间帮助类
为了方便调用,将4个系统函数进行封装到一个类中SysTimeHelper,如下所示:
public class SysTimeHelper
{
  [DllImport("kernel32.dll")]
  public static extern bool SetSystemTime(ref SystemTime st);
 
  [DllImport("Kernel32.dll")]
  public static extern bool SetLocalTime(ref SystemTime st);
 
  [DllImport("Kernel32.dll")]
  public static extern void GetSystemTime(ref SystemTime st);
 
  [DllImport("Kernel32.dll")]
  public static extern void GetLocalTime(ref SystemTime st);
 
  public static string GetLocalTime()
  {
    SystemTime st = new SystemTime();
    GetLocalTime(ref st);
    return st.ToString();
  }
 
  public static bool SetLocalTimeByStr(string timestr)
  {
    bool flag = false;
    SystemTime sysTime = new SystemTime();
    DateTime dt = Convert.ToDateTime(timestr);
    sysTime.wYear = Convert.ToUInt16(dt.Year);
    sysTime.wMonth = Convert.ToUInt16(dt.Month);
    sysTime.wDay = Convert.ToUInt16(dt.Day);
    sysTime.wHour = Convert.ToUInt16(dt.Hour);
    sysTime.wMinute = Convert.ToUInt16(dt.Minute);
    sysTime.wSecond = Convert.ToUInt16(dt.Second);
    try
    {
      flag = SetLocalTime(ref sysTime);
    }
    catch (Exception ex)
    {
      string e = ex.Message;
      return false;
    }
    return flag;
  }
 
  /// <summary>     
  /// 堆代码 duidaima.com   
  /// 时间戳转为C#格式时间        
  /// </summary>        
  /// <param name=”timeStamp”></param>        
  /// <returns></returns>        
  public static DateTime ConvertStringToDateTime(string timeStamp)
  {
    DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
    long lTime = long.Parse(timeStamp + "0000");
    TimeSpan toNow = new TimeSpan(lTime);
    return dtStart.Add(toNow);
  }
  /// <summary>
  /// 时间戳转为C#格式时间10位
  /// </summary>
  /// <param name="timeStamp">Unix时间戳格式</param>
  /// <returns>C#格式时间</returns>
  public static DateTime GetDateTimeFrom1970Ticks(long curSeconds)
  {
    DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
    return dtStart.AddSeconds(curSeconds);
  }
 
}
3. 函数调用
在页面调用时,即可通过SysTimeHelper帮助类,进行获取和修改系统时间。如下所示:
public partial class MainWindow : Window
{
  public MainWindow()
  {
    InitializeComponent();
  }
 
  private void Window_Loaded(object sender, RoutedEventArgs e)
  {
    var time = SysTimeHelper.GetLocalTime();
    this.txtTime.Text = time;
  }
 
  private void Button_Click(object sender, RoutedEventArgs e)
  {
    var time = this.txtTime.Text;
    bool flag = SysTimeHelper.SetLocalTimeByStr(time);
    if(flag)
    {
      MessageBox.Show("设置成功");
    }
    else
    {
      MessageBox.Show("设置失败");
    }
  }
}
实例演示

通过VS运行程序,在打开程序时,获取时间,然后手动修改时间,点击设置,如下所示:

如果设置过后,想要回复,可通过设置页面【同步时钟】进行恢复,如下所示:

注意,如果在调试时,设置失败【SetLocalTime返回false】,可通过【以管理员身份运行】打开Visual Studio,如下所示:

或者直接通过管理员身份运行程序,如下所示:

以上就是【C# 设置客户端系统时间】的全部内容,关于更多详细内容,可参考官方文档。希望能够一起学习,共同进步。
用户评论