查找將時間倒退 1 小時的 Windows 程序
我有一台 Windows 機器,它會定期更改系統時間,原因不明。它似乎每小時都會發生。
這台 Windows 機器是一個虛擬機(Parallels Desktop 9、Win7 來賓、OSX 主機)。它有一個執行的 NTP 服務 ( NetTime ) 可以迅速糾正錯誤,但在更改和糾正之間的那短短幾秒鐘內,它會導致問題。
我檢查過:
- 虛擬機時間同步被禁用
- Windows“網際網路時間”被禁用
- Windows 時間服務已禁用
- 我只執行一個 NTP 客戶端,每 15 分鐘更新一次
有一個並發症。我們提供夜間天文服務。為了避免自動 DST 更改引起的問題,我們禁用自動 DST 更改,並在當天晚些時候手動將機器時區設置為具有正確偏移的區域。例如,在西班牙,現在是 DST。標準時間為 UTC+1,DST 為 UTC+2。DST 更改後的第二天早上,我們將機器時區設置為希臘 UTC+2。主機配置正常(正確的時區,自動 DST 更改)。複雜之處在於時鐘會在 UTC+1(DST 之前的時間)變回目前時間。
一些過程正在改變這一點。可能它有自己的時區設置。但我一直無法追踪它。更改記錄在系統日誌中。有兩個關鍵條目:時間設置不正確,以及何時更正:(
完全披露,事件日誌按事件 ID = 1 過濾,但其他事件看起來毫無意義)。
有趣的是這些發生的規律性(每小時,到第二次)。更有趣的是,這些都是正常執行時間。我可以在任務管理器中查看系統正常執行時間,當它超過一個小時時,時鐘會改變。
同樣有趣的是查看活動細節:
- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> - <System> <Provider Name="Microsoft-Windows-Kernel-General" Guid="{GUID}" /> <EventID>1</EventID> <Version>0</Version> <Level>4</Level> <Task>0</Task> <Opcode>0</Opcode> <Keywords>0x8000000000000010</Keywords> <TimeCreated SystemTime="2018-04-18T00:31:28.500000000Z" /> <EventRecordID>500706</EventRecordID> <Correlation /> <Execution ProcessID="4" ThreadID="56" /> <Channel>System</Channel> <Computer>T07-VM-GUEST</Computer> <Security UserID="SID" /> </System> - <EventData> <Data Name="NewTime">2018-04-18T00:31:28.500000000Z</Data> <Data Name="OldTime">2018-04-18T01:31:28.861800000Z</Data> </EventData> </Event>
我們可以看到此事件從 01:31 更改為 00:31(UTC 時間,本地時間 03:31 到 02:31,如事件日誌中所示)。特別有趣的是這一行:
<Execution ProcessID="4" ThreadID="56" />
PID 4 是
System
程序:使用 ProcessExplorer,我可以檢查系統程序(PID 4),並且可以看到有關 ThreadId 56 的一些詳細資訊(假設它們沒有被回收並且我正在查看正確的程序):
但這對我來說都是胡言亂語。我在這裡可以看到的唯一有意義的事情是開始時間,以及它與時鐘更改事件時間的關係(正如我上面所說,每小時與正常執行時間同步)。
This answer談到在安全日誌中查找時間更改,並且由 NetTime 服務發起的所有更改都在其中。但是有問題的更改可疑地失去了:
我的分析是否正確,如果正確,為什麼系統程序每小時都會更改我的系統時鐘?
好的,就像所有最糟糕的問題類型一樣,這個問題有兩個部分。
- Windows 每小時將系統時間更新為硬體時鐘。(請注意,它也在啟動時執行此操作,從而加快了測試速度)
- Parallels 錯誤地虛擬化硬體時鐘。我不得不說我使用的是舊版本的 Parallels (PD9),我希望他們現在已經解決了這個問題。
我還沒有找到任何關於此的明確聲明,但我看到很多人在我的鞋子裡確認同樣的事情:Windows 每小時讀取實時時鐘(RTC,或 BIOS 中的硬體時鐘)並重新同步用它。請參閱參考資料:#1、#2、#3、#4。
顯然,其中大部分與 RTC 故障、BIOS 電池耗盡或使用 *nix 作業系統(將 UTC 儲存在 RTC,而不是本地時間)的雙啟動有關。但事實仍然是 Windows 每小時都會這樣做。我還沒有找到禁用此功能的方法。
此外,Parallels 本身不保留硬體時鐘,而是在 VM 配置文件中保留一個偏移量(相對於系統時間)。問題是這個偏移量沒有正確考慮 DST。例如,我在西班牙馬德里有一台主機 Mac,通常是 UTC+1,但目前在夏令時是 UTC+2。當我在我的訪客機器中設置時間時,Parallels 會計算我的訪客時間和沒有 DST 的主機時區之間的差異。
舉個例子:
目前時間是UTC 00:00。
馬德里標準時間是 UTC+1,所以是 01:00。除了目前是 DST、UTC+2、02:00。我將我的訪客機器設置為 02:00,Windows 嘗試將其寫入 RTC,Parallels 計算我的訪客時間與馬德里標準 (01:00) 之間的差異,並保存
<TimeShift>-3600</TimeShift>
到配置文件中(文件僅在重啟時更新,我想像一下這個變數在執行時在記憶體中被跟踪)。所以每次 Windows 讀取 RTC(Parallels 讀取主機系統時間)時,它認為 RTC 設置為 HostTime-3600s(-1 小時)並更新時間。我知道我的訪客機器有一個複雜的設置(手動設置為開羅以查找沒有 DST 的時區),我想我會給 Parallels 懷疑的好處,看看它是否在設置為正確時區的訪客和主機上都能正常工作(馬德里與 DST)。不,它仍然搞砸了。
解決方案:
我找不到禁用 Windows 每小時讀取 RTC 的方法,因此我暫時強制主機使用不使用 DST 的時區(例如 Cairo,UTC+2)。這行得通。當我將訪客時間保存到 02:00 並且開羅時間 (UTC+2) 為 02:00 時,Parallels 保存
<TimeShift>0</TimeShift>
.醜陋。