Альтернатива RunAsDate с недостающими частями
RunAsDate уже много лет остаётся ответом на «запусти эту программу с другой датой в Windows», и это хороший ответ. Эта страница о том, чем они отличаются и где RunAsDate по-прежнему лучше.
Бок о бок
| RunAsDate | Chrono Mock | |
|---|---|---|
| Запускает приложение с поддельной датой | да | да |
| Не трогает системные часы | да | да |
| Перехватываемые функции времени | 5 | 44 (30 сдвигаются, 14 только считаются) |
| Часы быстрее настоящего времени | не предлагается | любой целочисленный множитель |
| Остановка часов | да, по умолчанию | да |
| Скачок во время работы приложения | только возврат к реальной дате через заданное число секунд | вперёд и назад, на любой момент |
| Часовой пояс только для этого процесса | не описано | да, фиксированное смещение |
| Дочерние процессы наследуют сессию | не описано | да |
| Подключение к уже запущенному приложению | да, начиная с версии 1.40 | нет - он запускает приложение сам |
| Несколько приложений с разными датами одновременно | да | нет - одна сессия за раз |
| Говорит, сработало ли | нет | вердикт, по каналам, со счётчиками вызовов |
| Приложения Electron и Chromium | не описано | отдельный механизм |
| Командная строка для CI | да | да, с кодами завершения и JSON |
| Исходный код | фриварь, закрытый | GPL-3.0 |
| Размер | загрузка 47 КБ, 57 КБ для 64 бит | ~2,4 МБ командная строка, ~70 МБ с окном |
| Старые версии 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 КБ, у него нет окна, которое нужно изучать, и он делает именно это уже много лет.
- Вы на более старой Windows. RunAsDate доходит до Windows 2000. Этот инструмент рассчитан на Windows 10 и 11 и на более старых не тестировался.
- Размер имеет значение. Загрузка в 47 КБ против ~2,4 МБ для командной строки или ~70 МБ с окном - это не близкое сравнение.
- Вердикт вам не нужен. Измерение покрытия означает необходимость читать результат. Если тест одноразовый, это лишние хлопоты, о которых вы не просили.
- Приложение уже запущено. RunAsDate с версии 1.40 умеет подключаться к работающему процессу. Chrono Mock запускает приложение сам, поэтому приложение, которое нельзя перезапустить, ему недоступно.
- Вам нужны несколько приложений с разными датами одновременно. RunAsDate даёт каждому свою дату. Chrono Mock ведёт одну сессию за раз.
Они к тому же могут сосуществовать. Ничто здесь не мешает вам оставить RunAsDate для быстрого случая.
Для чего не предназначен ни один из них
Оба инструмента попадаются в поисковых запросах о продлении пробных периодов. Этот не предназначен для такого, и ни один пример, сценарий или страница здесь никогда этого не покажут. Chrono Mock предназначен для тестирования программного обеспечения, за которое вы отвечаете, — вашего собственного истечения лицензии, вашей собственной логики продления, вашего собственного отчёта на конец месяца.
Это также случай, в котором работа наименее вероятна. Защита лицензии обычно читает время путями, выбранными так, чтобы их было трудно перехватить, — общая страница данных в пользовательском режиме, прямые системные вызовы, сервер, — а откат часов назад — условие, которое такой код пишут, чтобы обнаруживать. Аудит скажет вам, что не сработало, и это честный ответ, а не полезный.