C# 通过Win32API设置客户端体系时间

打印 上一主题 下一主题

主题 968|帖子 968|积分 2904

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

 
在windows体系中,设置体系时间,主要通过win32提供的API来实现,如下所示:

  • SetLocalTime 设置体系的本地化时间
  • GetLocalTime 获取体系的本地化时间
  • SetSystemTime 设置体系的Utc时间
  • GetSystemTime 获取体系的Utc时间
 
焦点代码

 
时间结构体

 
在上述四个体系函数中,都需要一个时间类型的结构体,包含时分秒,年代日。如下所示:
  1. [StructLayout(LayoutKind.Sequential)]
  2. public struct SystemTime
  3. {
  4.         public ushort wYear;
  5.         public ushort wMonth;
  6.         public ushort wDayOfWeek;
  7.         public ushort wDay;
  8.         public ushort wHour;
  9.         public ushort wMinute;
  10.         public ushort wSecond;
  11.         public ushort wMilliseconds;
  12.         public override string ToString()
  13.         {
  14.                 return $"{wYear}-{wMonth}-{wDay} {wHour}:{wMinute}:{wSecond}.{wMilliseconds}";
  15.         }
  16. }
复制代码
 
体系时间帮助类

 
为了方便调用,将4个体系函数进行封装到一个类中SysTimeHelper,如下所示:
  1. public class SysTimeHelper
  2. {
  3.         [DllImport("kernel32.dll")]
  4.         public static extern bool SetSystemTime(ref SystemTime st);
  5.         [DllImport("Kernel32.dll")]
  6.         public static extern bool SetLocalTime(ref SystemTime st);
  7.         [DllImport("Kernel32.dll")]
  8.         public static extern void GetSystemTime(ref SystemTime st);
  9.         [DllImport("Kernel32.dll")]
  10.         public static extern void GetLocalTime(ref SystemTime st);
  11.         public static string GetLocalTime()
  12.         {
  13.                 SystemTime st = new SystemTime();
  14.                 GetLocalTime(ref st);
  15.                 return st.ToString();
  16.         }
  17.         public static bool SetLocalTimeByStr(string timestr)
  18.         {
  19.                 bool flag = false;
  20.                 SystemTime sysTime = new SystemTime();
  21.                 DateTime dt = Convert.ToDateTime(timestr);
  22.                 sysTime.wYear = Convert.ToUInt16(dt.Year);
  23.                 sysTime.wMonth = Convert.ToUInt16(dt.Month);
  24.                 sysTime.wDay = Convert.ToUInt16(dt.Day);
  25.                 sysTime.wHour = Convert.ToUInt16(dt.Hour);
  26.                 sysTime.wMinute = Convert.ToUInt16(dt.Minute);
  27.                 sysTime.wSecond = Convert.ToUInt16(dt.Second);
  28.                 try
  29.                 {
  30.                         flag = SetLocalTime(ref sysTime);
  31.                 }
  32.                 catch (Exception ex)
  33.                 {
  34.                         string e = ex.Message;
  35.                         return false;
  36.                 }
  37.                 return flag;
  38.         }
  39.         /// <summary>        
  40.         /// 时间戳转为C#格式时间        
  41.         /// </summary>        
  42.         /// <param name=”timeStamp”></param>        
  43.         /// <returns></returns>        
  44.         public static DateTime ConvertStringToDateTime(string timeStamp)
  45.         {
  46.                 DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
  47.                 long lTime = long.Parse(timeStamp + "0000");
  48.                 TimeSpan toNow = new TimeSpan(lTime);
  49.                 return dtStart.Add(toNow);
  50.         }
  51.         /// <summary>
  52.         /// 时间戳转为C#格式时间10位
  53.         /// </summary>
  54.         /// <param name="timeStamp">Unix时间戳格式</param>
  55.         /// <returns>C#格式时间</returns>
  56.         public static DateTime GetDateTimeFrom1970Ticks(long curSeconds)
  57.         {
  58.                 DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
  59.                 return dtStart.AddSeconds(curSeconds);
  60.         }
  61. }
复制代码
 
函数调用

 
在页面调用时,即可通过SysTimeHelper帮助类,进行获取和修改体系时间。如下所示:
 
  1. public partial class MainWindow : Window
  2. {
  3.         public MainWindow()
  4.         {
  5.                 InitializeComponent();
  6.         }
  7.         private void Window_Loaded(object sender, RoutedEventArgs e)
  8.         {
  9.                 var time = SysTimeHelper.GetLocalTime();
  10.                 this.txtTime.Text = time;
  11.         }
  12.         private void Button_Click(object sender, RoutedEventArgs e)
  13.         {
  14.                 var time = this.txtTime.Text;
  15.                 bool flag = SysTimeHelper.SetLocalTimeByStr(time);
  16.                 if(flag)
  17.                 {
  18.                         MessageBox.Show("设置成功");
  19.                 }
  20.                 else
  21.                 {
  22.                         MessageBox.Show("设置失败");
  23.                 }
  24.         }
  25. }
复制代码
 
实例演示

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

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

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

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

 
以上就是【C# 通过Win32API设置客户端体系时间】的全部内容,希望可以抛砖引玉,一起学习,共同进步。
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

笑看天下无敌手

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表