天天看點

python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)

家裡有台很多年前買的電腦,CMOS電池殘廢了,經常遇到開機後系統時間被重置的情況,老媽向我反映用起來很不友善。于是身為一個程式員的我想到寫個小工具來幫老媽排憂解難。話不多說,小工具需求如下:

功能需求 -- 電腦開機後自動執行時間同步

非功能需求 -- 安裝執行簡單,無需安裝額外環境

一、代碼實作

基于以上需求,思路如下:通路網絡擷取中原標準時間,然後調用指令行來設定系統時間。程式寫成Windows Service,并設定為開機自動運作。正好前段時間在學習Python,是以打算用Python來寫這個工具。具體代碼如下:

python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)
python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)

擷取網絡時間

1 defgetBeijinTime():2 """

3 擷取中原標準時間4 """

5 try:6 conn = httplib.HTTPConnection("www.beijing-time.org")7 conn.request("GET", "/time.asp")8 response =conn.getresponse()9 printresponse.status, response.reason10 if response.status == 200:11 #解析響應的消息

12 result =response.read()13 logging.debug(result)14 data = result.split("\r\n")15 year = data[1][len("nyear")+1 : len(data[1])-1]16 month = data[2][len("nmonth")+1 : len(data[2])-1]17 day = data[3][len("nday")+1 : len(data[3])-1]18 #wday = data[4][len("nwday")+1 : len(data[4])-1]

19 hrs = data[5][len("nhrs")+1 : len(data[5])-1]20 minute = data[6][len("nmin")+1 : len(data[6])-1]21 sec = data[7][len("nsec")+1 : len(data[7])-1]22

23 beijinTimeStr = "%s/%s/%s %s:%s:%s" %(year, month, day, hrs, minute, sec)24 beijinTime = time.strptime(beijinTimeStr, "%Y/%m/%d %X")25 returnbeijinTime26 except:27 logging.exception("getBeijinTime except")28 return None

python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)
python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)

同步本地系統時間

1 defsyncLocalTime():2 """

3 同步本地時間4 """

5 logging.info("current local time is: %d-%d-%d %d:%d:%d" % time.localtime()[:6])6

7 beijinTime =getBeijinTime()8 if beijinTime isNone:9 logging.info("get beijinTime is None, will try again in 30 seconds...")10 timer = threading.Timer(30.0, syncLocalTime)11 timer.start();12 else:13 logging.info("get beijinTime is: %d-%d-%d %d:%d:%d" % beijinTime[:6])14

15 tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec = beijinTime[:6]16 importos17 os.system("date %d-%d-%d" % (tm_year, tm_mon, tm_mday)) #設定日期

18 os.system("time %d:%d:%d.0" % (tm_hour, tm_min, tm_sec)) #設定時間

19 logging.info("syncLocalTime complete, current local time: %d-%d-%d %d:%d:%d \n" % time.localtime()[:6])

二、部署安裝

為了讓Python程式能以Windows服務的方式運作,需要用到py2exe(用來把Python程式編譯成exe)和Python Win32 Extensions 。(py2exe把Python代碼編譯成Winodws服務時依賴此元件)下載下傳并安裝這兩個元件。安裝完畢後,在Python的安裝目錄下找到py2exe的Windows Service示例({PythonRoot}\Lib\site-packages\py2exe\samples\advanced\MyService.py)。然後仿照這個示例将上面的代碼完善一下。

python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)
python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)

Windows服務示例

1 importwin32serviceutil2 importwin32service3 importwin32event4 importwin32evtlogutil5

6 classSynctimeService(win32serviceutil.ServiceFramework):7 _svc_name_ = "Synctime"

8 _svc_display_name_ = "Synctime"

9 _svc_description_ = "Synchronize local system time with beijin time"

10 _svc_deps_ = ["EventLog"]11

12 def __init__(self, args):13 win32serviceutil.ServiceFramework.__init__(self, args)14 self.hWaitStop =win32event.CreateEvent(None, 0, 0, None)15

16 defSvcStop(self):17 self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)18 win32event.SetEvent(self.hWaitStop)19

20 defSvcDoRun(self):21 importservicemanager22

23 #Write a 'started' event to the event log...

24 win32evtlogutil.ReportEvent(self._svc_name_,25 servicemanager.PYS_SERVICE_STARTED,26 0, #category

27 servicemanager.EVENTLOG_INFORMATION_TYPE,28 (self._svc_name_, ''))29

30 #wait for beeing stopped...

31 win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)32

33 #and write a 'stopped' event to the event log.

34 win32evtlogutil.ReportEvent(self._svc_name_,35 servicemanager.PYS_SERVICE_STOPPED,36 0, #category

37 servicemanager.EVENTLOG_INFORMATION_TYPE,38 (self._svc_name_, ''))39

40 if __name__ == '__main__':41 #Note that this code will not be run in the 'frozen' exe-file!!!

42 win32serviceutil.HandleCommandLine(SynctimeService)

之後,再編寫一個steup.py檔案用來生成安裝檔案。

python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)
python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)

Setup.py

1 from distutils.core importsetup2 importpy2exe3

4 setup(5 #The first three parameters are not required, if at least a

6 #'version' is given, then a versioninfo resource is built from

7 #them and added to the executables.

8 version = "0.0.1",9 description = "Synchroniz local system time with beijin time",10 name = "sysctime",11

12 #targets to build

13 #console = ["synctime.py"],

14 service=["synctime"]15 )

編譯生成windows程式,如下圖:

python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)

然後在控制台中運作:setup.py py2exe ,一切順利的話會在目前目錄下生成build和dist目錄。

python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)

控制台目錄切換到dist目錄,找到synctime.exe,在指令行中運作:

synctime.exe –install (-remove)  安裝或移除時間同步服務。

現在可以運作services.msc檢視服務運作情況

python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)

可以看到服務并沒有啟動,而且啟動方式為手動。在這裡可以右擊服務選擇屬性手動把服務啟動起來,并且設定為服務自動啟動。

好吧,我承認。這樣操作跟上面的需求有點出入了,略顯麻煩。為了解決這個問題,自然想到的是用批處理來做。在dist目錄下分别建兩個批處理檔案:

python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)
python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)

installservice.bat

1 @echo off

2

3 ::安裝windows服務

4 echo 正在安裝服務,請稍候...

5 synctime.exe -install6

7 ::設定服務自動啟動

8 echo 正在啟動服務...

9 sc config Synctime start=AUTO10

11 ::啟動服務

12 sc startSynctime13

14 echo 服務啟動成功, 按任意鍵繼續...

15 pause

python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)
python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)

removeserivce.bat

1 @echo off

2

3 ::停止服務

4 echo 正在停止服務,請稍候...

5 sc stop Synctime6

7 echo 正在解除安裝服務...

8 ::删除windows服務

9 synctime.exe -remove10

11 echo 服務解除安裝完成,請按任意鍵繼續剩餘解除安裝...

12 pause

好了,現在可以把dist打個包發給老媽用了。但是,這樣發個一個壓縮包,看起來也太不專業了。解決的辦法是打一個安裝包,把bat腳本打到安裝包裡,在安裝程式時由安裝包調用。這裡我用的是NISI(使用HM VNISEdit打包向導來生成打包腳本非常友善)。

三、最終安裝效果圖

python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)
python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)
python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)
python系統時間同步_時間同步小工具(Python + Windows Service + NSIS)

四、結尾

遺留的問題:

1、從上面的截圖可以看到,安裝程式在調用批處理時會顯示出控制台視窗。這個問題我在網上查找資料,NSIS有相關的插件可以隐藏控制台視窗調用bat檔案。

2、我源代碼中有寫日志檔案的操作,但是以Windows服務的方式運作後,日志檔案不能寫了,不知道有沒有好的解決辦法。

3、360 ...真是要人命啊....Orz..

最後附上源代碼及時間同步工具安裝包

版權說明:本文章版權歸本人及部落格園共同所有,未經允許請勿用于任何商業用途。轉載請标明原文出處: