C#通過Win32API設(shè)置客戶端系統(tǒng)時(shí)間的方法詳解
在日常工作中,有時(shí)可能會(huì)需要獲取或修改客戶端電腦的系統(tǒng)時(shí)間,比如軟件設(shè)置了Licence有效期,預(yù)計(jì)2024-06-01 00:00:00到期,如果客戶手動(dòng)修改了客戶端電腦時(shí)間,往前調(diào)整了一年,則軟件就可以繼續(xù)使用一年,如此循環(huán)往復(fù),則Licence將形同虛設(shè)。所以有時(shí)候需要校驗(yàn)客戶端電腦時(shí)間和服務(wù)器端時(shí)間,是否一致,如果不一致,則需要修改客戶端電腦時(shí)間或進(jìn)行系統(tǒng)提示。本文以一個(gè)簡(jiǎn)單的小例子,簡(jiǎn)述如何通過C#獲取和設(shè)置客戶端電腦的系統(tǒng)時(shí)間,僅供學(xué)習(xí)分享使用,如有不足之處,還請(qǐng)指正。
涉及知識(shí)點(diǎn)
在windows系統(tǒng)中,設(shè)置系統(tǒng)時(shí)間,主要通過win32提供的API來實(shí)現(xiàn),如下所示:
- SetLocalTime 設(shè)置系統(tǒng)的本地化時(shí)間
- GetLocalTime 獲取系統(tǒng)的本地化時(shí)間
- SetSystemTime 設(shè)置系統(tǒng)的Utc時(shí)間
- GetSystemTime 獲取系統(tǒng)的Utc時(shí)間
核心代碼
時(shí)間結(jié)構(gòu)體
在上述四個(gè)系統(tǒng)函數(shù)中,都需要一個(gè)時(shí)間類型的結(jié)構(gòu)體,包含時(shí)分秒,年月日。如下所示:
[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}"; } }
系統(tǒng)時(shí)間幫助類
為了方便調(diào)用,將4個(gè)系統(tǒng)函數(shù)進(jìn)行封裝到一個(gè)類中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> /// 時(shí)間戳轉(zhuǎn)為C#格式時(shí)間 /// </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> /// 時(shí)間戳轉(zhuǎn)為C#格式時(shí)間10位 /// </summary> /// <param name="timeStamp">Unix時(shí)間戳格式</param> /// <returns>C#格式時(shí)間</returns> public static DateTime GetDateTimeFrom1970Ticks(long curSeconds) { DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); return dtStart.AddSeconds(curSeconds); } }
函數(shù)調(diào)用
在頁(yè)面調(diào)用時(shí),即可通過SysTimeHelper幫助類,進(jìn)行獲取和修改系統(tǒng)時(shí)間。如下所示:
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("設(shè)置成功"); } else { MessageBox.Show("設(shè)置失敗"); } } }
實(shí)例演示
通過VS運(yùn)行程序,在打開程序時(shí),獲取時(shí)間,然后手動(dòng)修改時(shí)間,點(diǎn)擊設(shè)置,如下所示:
如果設(shè)置過后,想要回復(fù),可通過設(shè)置頁(yè)面【同步時(shí)鐘】進(jìn)行恢復(fù),如下所示:
注意,如果在調(diào)試時(shí),設(shè)置失敗【SetLocalTime返回false】,可通過【以管理員身份運(yùn)行】的方式打開Visual Studio,如下所示:
或者直接通過【以管理員身份運(yùn)行】啟動(dòng)程序,如下所示:
以上就是C#通過Win32API設(shè)置客戶端系統(tǒng)時(shí)間的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于C# Win32API系統(tǒng)時(shí)間的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C# BackgroundWorker組件學(xué)習(xí)入門介紹
一個(gè)程序中需要進(jìn)行大量的運(yùn)算,并且需要在運(yùn)算過程中支持用戶一定的交互,為了獲得更好的用戶體驗(yàn),使用BackgroundWorker來完成這一功能2013-10-10C#?使用PrintDocument類打印標(biāo)簽的方法
本文介紹打印機(jī)初步配置,以及實(shí)現(xiàn)方法,標(biāo)簽主要展示資產(chǎn)基本信息以及二維碼,對(duì)C#?使用PrintDocument類打印標(biāo)簽的詳細(xì)過程感興趣的朋友一起看看吧2022-04-04C#進(jìn)行圖像處理的常見方法(Bitmap,BitmapData,IntPtr)使用詳解
這篇文章主要為大家詳細(xì)介紹了C#進(jìn)行圖像處理的幾個(gè)常見方法(Bitmap,BitmapData,IntPtr)具體使用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2024-01-01Unity實(shí)現(xiàn)鼠標(biāo)點(diǎn)2D轉(zhuǎn)3D進(jìn)行旋轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)鼠標(biāo)點(diǎn)2D轉(zhuǎn)3D進(jìn)行旋轉(zhuǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04C#多線程同步lock、Mutex的實(shí)現(xiàn)
本文主要介紹了C#多線程同步lock、Mutex的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05C# 通過反射初探ORM框架的實(shí)現(xiàn)原理(詳解)
下面小編就為大家分享一篇C# 通過反射初探ORM框架的實(shí)現(xiàn)原理詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2017-12-12