足りなかった部分を補う、RunAsDate の代替ツール
RunAsDate は長年にわたり、「Windows でこのプログラムを別の日付で実行する」ための定番の答えであり、優れたツールです。このページでは、両者がどこで異なるか、そして RunAsDate のほうが今でも向いている場面を説明します。
並べて比較
| RunAsDate | Chrono Mock | |
|---|---|---|
| 1 つのアプリを偽の日付で実行する | 対応 | 対応 |
| システム時計に手を触れない | 対応 | 対応 |
| フックする時刻関数 | 5 | 44(ずらす 30、数えるだけ 14) |
| 実時間より速い時計 | 非対応 | 任意の整数倍 |
| 時計を止める | 対応 (既定の動作) | 対応 |
| アプリ実行中のジャンプ | 指定した秒数の後に実際の日付へ戻るだけ | 前にも後ろにも、任意の時点へ |
| そのプロセスだけのタイムゾーン | 記載なし | 対応(固定オフセット) |
| 子プロセスがセッションを引き継ぐ | 記載なし | 対応 |
| すでに動いているアプリケーションへのアタッチ | 対応 (バージョン 1.40 以降) | 非対応 - アプリケーションを自分で起動する |
| 異なる日付で複数のアプリケーションを同時に | 対応 | 非対応 - セッションは一度に 1 つ |
| 効いたかどうかを教えてくれる | なし | 判定、チャネルごと、呼び出し回数付き |
| 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 は、同じ一文を測定すべきものとして扱います。すべてのセッションは、判定、アプリが実際に読んだチャネルとそれぞれの回数、取りこぼしたチャネル、そしてアプリが時計を尋ねる前にネットワーク接続を開くのが観測されたときの警告で終わります。
時刻がずれているように見えて実はずれていないアプリは、一度も起動しなかったアプリより悪質です。何の意味もない合格テストを生み出すからです。監査のしくみ →
5 つの関数か、44 個のチャネルか
RunAsDate は GetSystemTime、GetLocalTime、GetSystemTimeAsFileTime、NtQuerySystemTime、GetSystemTimePreciseAsFileTime をフックします。壁時計はそこで読まれるので、非常に多くのアプリにはこれで本当に十分です。
残りの領域は、日付に依存するコードが潜みやすい場所です。
- タイムゾーン - それを返す 2 つの関数と、ゾーン間を変換する 6 つの関数。レポートが違う日に載ってしまう原因はここにあります
- 経過時間の軸 - ティック数と、バイアスのない割り込み時間。試用期間のカウントダウンがたいてい測っているものです。
- スリープ - 遅延が実際の時計ではなくセッションの時計での遅延になるように。そしてオブジェクト待機 - 回数は数えますが、長さは実際のままです
- タイマー - 待機可能タイマー、ウィンドウタイマー、スレッドプールタイマー、マルチメディアタイマー。
- プロセス作成 - インストーラーの子プロセスが、現在の日付ではなく同じセッションで動くように。
- ネットワーク接続 - 時刻がサーバーから来ているかもしれない兆候として数えます
44 のうち 30 はセッションの時計に載せ替えます。残りの 14 は数えるだけで実際の値のままにするので、レポートはずらしたとは主張せずにそれらを挙げます。壁時計とタイムゾーンはすべてのセッションでずらします。経過時間の軸と待機は --scale-duration で、高分解能カウンターは --scale-qpc で求めたときに監視します。
RunAsDate のほうが向いている場合
本当に、しかもめずらしくありません。
- 通常の速度で、1 つの日付だけを今すぐ使いたいとき。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 が一度に扱うセッションは 1 つです。
両者は共存もできます。手軽な用途のために RunAsDate を手元に残しておくことを、ここにあるものが妨げることはありません。
どちらも目的としていないこと
どちらのツールも、試用期間の延長に関する検索結果に現れます。このツールは、そのために作られたものではなく、それを示す例、シナリオ、ページは、ここには今後も存在しません。Chrono Mock は、自分が責任を負うソフトウェア、つまり自社のライセンスの期限切れ、自社の更新ロジック、自社の月末レポートをテストするためのものです。
それは、最も動作しにくいケースでもあります。ライセンス保護は、傍受しにくい経路を選んで日常的に時刻を読みます。共有されたユーザーモードのデータページ、直接のシステムコール、サーバーなどです。そして時計の巻き戻しは、その種のコードが検出するように書かれている条件です。監査は、それが動作しなかったと教えてくれます。これは役に立つ答えではなく、正直な答えです。