在日常工作中,有时可能会需要获取或修改客户端电脑的系统时间,比如软件设置了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系统时间的资料请关注代码网其它相关文章!
发表评论