被时间投喂过 发表于 2024-6-18 02:25:27

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

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

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

[*]SetLocalTime 设置系统的本地化时间
[*]GetLocalTime 获取系统的本地化时间
[*]SetSystemTime 设置系统的Utc时间
[*]GetSystemTime 获取系统的Utc时间
 
核心代码

 
时间结构体

 
在上述四个系统函数中,都需要一个时间类型的结构体,包含时分秒,年月日。如下所示:

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
{
       
        public static extern bool SetSystemTime(ref SystemTime st);

       
        public static extern bool SetLocalTime(ref SystemTime st);

       
        public static extern void GetSystemTime(ref SystemTime st);

       
        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设置客户端系统时间】的全部内容,希望可以抛砖引玉,一起学习,共同进步。
 

来源:https://www.cnblogs.com/hsiang/p/18251106
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: C# 通过Win32API设置客户端系统时间