RunAsDate 替代品,補上了缺少的部分
多年來,RunAsDate 一直是「在 Windows 上讓這個程式以另一個日期執行」的答案,而且是個好答案。本頁談的是兩者的不同之處,以及 RunAsDate 在哪些情況下仍是更好的選擇。
並排比較
| RunAsDate | Chrono Mock | |
|---|---|---|
| 讓一個應用程式以虛擬日期執行 | 是 | 是 |
| 不動系統時鐘 | 是 | 是 |
| 被攔截的時間函式 | 5 | 44(30 個被偏移,14 個僅計數) |
| 比真實時間更快的時鐘 | 不提供 | 任意整數倍率 |
| 凍結時鐘 | 是,預設如此 | 是 |
| 應用程式執行期間跳轉 | 只能在設定的秒數後回到真實日期 | 向前和向後,跳到任意時刻 |
| 僅對該處理序生效的時區 | 文件中未提及 | 是,固定偏移量 |
| 子處理序繼承工作階段 | 文件中未提及 | 是 |
| 附加到已在執行的應用程式 | 是,自 1.40 版起 | 否 - 它自己啟動應用程式 |
| 同時以不同日期執行多個應用程式 | 是 | 否 - 一次只有一個工作階段 |
| 告訴你是否生效 | 否 | 判定,逐個通道,附呼叫次數 |
| Electron 與 Chromium 應用程式 | 文件中未提及 | 獨立的機制 |
| 可用於 CI 的命令列 | 是 | 是,附結束代碼與 JSON |
| 原始碼 | 免費軟體,封閉原始碼 | GPL-3.0 |
| 大小 | 下載 47 KB,64 位元版 57 KB | 命令列版約 2.4 MB,含視窗版約 70 MB |
| 舊版 Windows | 最早到 Windows 2000 | Windows 10 與 11 |
「文件中未提及」的意思是 RunAsDate 的頁面沒有提到這項功能,並不是宣稱該工具沒有這項功能。 除非開啟 RunAsDate 的選項 Move the time forward according to the real time,否則它的時鐘靜止不動。
最重要的差別
不在於通道的數量。而在於 RunAsDate 在它自己的文件裡老實地告訴你,它「對從其他來源取得目前日期/時間的應用程式不起作用」——然後讓你自己去弄清楚你的應用程式是不是其中之一。
Chrono Mock 把同一句話當作需要量測的東西。每次工作階段都以一個判定、應用程式實際讀取過的通道及各自的次數、被遺漏的通道,以及在應用程式還沒詢問時鐘之前就被發現開啟了網路連線時的警告結束。
一個看起來時間被改了、其實沒有的應用程式,比一個根本沒有啟動的應用程式更糟——它會產出一個毫無意義的通過的測試。 稽核是如何運作的 →
五個函式,還是 44 個通道
RunAsDate 攔截 GetSystemTime、GetLocalTime、GetSystemTimeAsFileTime、NtQuerySystemTime 與 GetSystemTimePreciseAsFileTime。對非常多的應用程式來說,這確實足夠了,因為掛鐘時間就是在這些地方被讀取的。
其餘的部分,則是與日期相關的程式碼容易藏身之處:
- 時區 - 回報時區的兩個函式,加上在時區之間換算的六個函式,報表落到錯誤日期正是因為它們
- 經過時間軸——計時刻度與無偏的中斷時間,試用期倒數通常量測的正是它們
- 休眠,讓延遲成為工作階段時鐘上的延遲,而不是真實時鐘上的延遲,還有物件等待,它們會被計數並保持真實時長
- 計時器——可等候計時器、視窗計時器、執行緒集區計時器與多媒體計時器
- 處理序建立,讓安裝程式的子處理序在同一個工作階段中執行,而不是跑在當下的日期
- 網路連線,作為時間可能來自伺服器的跡象而被計數
在 44 個通道中,30 個被換到工作階段時鐘上。其餘 14 個只計數並保持真實,所以報告會列出它們,而不會聲稱它們被偏移了。牆上時鐘和時區在每個工作階段中都會被偏移。經過時間軸和等待在你用 --scale-duration 要求時會被監看,高解析度計數器則用 --scale-qpc。
什麼時候 RunAsDate 是更好的選擇
說真的,而且並不少見:
- 你只需要一個日期、正常速度、馬上就要。RunAsDate 的下載不到 60 KB,沒有需要學習的視窗,多年來一直在做的正是這件事。
- 你在用較舊的 Windows。RunAsDate 最早支援到 Windows 2000。這個工具以 Windows 10 與 11 為目標,在更舊的系統上沒有測試過。
- 體積很重要。47 KB 的下載對比命令列版約 2.4 MB 或含視窗版約 70 MB,根本不在同一個量級。
- 你不想要判定。量測涵蓋情況意味著要去讀結果。如果這個測試是用完即棄的,那就是你沒有要求的額外負擔。
- 應用程式已經在執行。RunAsDate 自 1.40 版起可以附加到正在執行的處理序。Chrono Mock 自己啟動應用程式,所以無法重新啟動的應用程式超出了它的能力範圍。
- 你想同時以不同日期執行多個應用程式。RunAsDate 會給每個應用程式各自的日期。Chrono Mock 一次只執行一個工作階段。
兩者也可以並存。這裡沒有任何東西會阻止你為快速的場景繼續保留 RunAsDate。
兩者都不是為此而生的
兩個工具都會出現在關於延長試用期的搜尋裡。這個工具不是為此而做的,這裡也不會有任何範例、預設或頁面示範這一點。Chrono Mock 是用來測試你自己負責的軟體的——你自己的授權到期、你自己的續約邏輯、你自己的月底報表。
這也是最不可能奏效的情形。授權保護通常透過刻意選擇的、難以攔截的途徑讀取時間——共用的使用者模式資料頁、直接系統呼叫、伺服器——而時鐘往後走正是這類程式碼被撰寫來偵測的情況。稽核會告訴你它沒有生效,這是誠實的答案,而不是有用的答案。