在日常工作中,有时可能会需要获取或修改客户端电脑的系统时间,比如软件设置了licence有效期,预计2024-06-01 00:00:00到期,如果客户手动修改了客户端电脑时间,往前调整了一年,则软件就可以继续使用一年,如此循环往复,则licence将形同虚设。所以有时候需要校验客户端电脑时间和服务器端时间,是否一致,如果不一致,则需要修改客户端电脑时间或进行系统提示。本文以一个简单的小例子,简述如何通过c#获取和设置客户端电脑的系统时间,仅供学习分享使用,如有不足之处,还请指正。
涉及知识点
在windows系统中,设置系统时间,主要通过win32提供的api来实现,如下所示:
- setlocaltime 设置系统的本地化时间
- getlocaltime 获取系统的本地化时间
- setsystemtime 设置系统的utc时间
- getsystemtime 获取系统的utc时间
核心代码
时间结构体
在上述四个系统函数中,都需要一个时间类型的结构体,包含时分秒,年月日。如下所示:
[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}"; } }
系统时间帮助类
为了方便调用,将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> /// 时间戳转为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); } }
函数调用
在页面调用时,即可通过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#通过win32api设置客户端系统时间的方法详解的详细内容,更多关于c# win32api系统时间的资料请关注代码网其它相关文章!
发表评论