ネイティブアプリの中の Web ページ
Web エンジンを内蔵したデスクトップアプリは、ページを別のサンドボックス化されたプロセスで実行します。ネイティブの仕組みはアプリ本体をカバーしますが、その境界で止まります。そのため、ウィンドウは指定した日付に移っても、その中のパネルは移りません。これはそのギャップを埋めるものです。
成功のように見える失敗
多くの Windows アプリは、外側はネイティブで、内側は Web ページです。設定画面、ダッシュボード、レポートビュー、ライセンスパネルなどを、2 度書く代わりに 1 度だけ HTML で作り、WebView2 や Qt WebEngine にホストさせています。
エンジンはそれらのページを独自のプロセスで実行し、そのプロセスはサンドボックス化されています。アプリにインジェクトしたライブラリは、そこには入りません。アプリが Windows に尋ねるものはすべてセッションの日付に移りますが、ページが JavaScript に尋ねるものは移りません。
- タイトルバー、ログ、ファイルは2038 年を示します。
- 同じウィンドウの中のパネルは今日を示します。
- エラーも警告も出ず、どちらの半分も同じくらい自信ありげに見えます。
テストは実行されたように見えるので、これはこのバグの高くつく形です。以前の挙動では、そのようなセッションをきれいな合格として報告していましたが、これはツールが裏付けられない主張でした。
セッションが代わりに行うこと
セッションは2 つの仕組みを同時に動かします。ネイティブのフックはいつもどおりアプリに入り、ページには、サンドボックス化されたレンダラーに到達できる唯一の方法、つまりエンジン自身に尋ねる方法で到達します。
起動時に、アプリは、そのエンジンにローカルのデバッグポートを開くよう求める 2 つの環境変数を引き継ぎます。これらはアプリがすでに渡しているスイッチを置き換えず、そこに追加されます。続いてセッションは自分のプロセスを監視してそのポートが現れるのを待ち、現れたら、その背後にあるすべてのページとすべての Worker がアプリと同じ時計に載ります。
開始点も速度もタイムラインも 1 つです。速度の変更やジャンプはアプリとそのページに同時に届き、ページのタイマーも独自のペースではなくアプリのペースで進みます。
既定でオンで、1 つのスイッチでオフにできます。オフにするとポートはまったく開かれず、ページは実際の時計のままになります。
# 設定は不要 - エンジンがあれば見つかる chrono run "C:\Program Files\YourApp\YourApp.exe" --at 2038-01-01T00:00:00 --mode x60 # あるいはページには手を触れず、ポートも開かない chrono run "C:\Program Files\YourApp\YourApp.exe" --at 2038-01-01T00:00:00 --no-embedded
レポートがページについて述べること
ページは、アプリ自身の数値には混ぜられません。プロセスとページは別のものであり、足し合わせると意味のない数値をでっち上げることになるため、別々の単位として数えられます。
- 見出しは両方を数えます -
processes: 4, contexts: 1。 - 各ページには専用の行が付きます。コマンドラインでは
context 1: page Date.now (12 calls)、ウィンドウの監査表では page Date.now - fake clock のようになります。 - 到達したエンジンはポート番号付きで名前が示されるので、セッションが操作しているページにそのまま自分の DevTools を向けられます。
ドライラン(dry run)なら、何かを起動する前に、ページに到達できるかどうかが分かります。判定の意味 →
始める前に知っておくべき 3 つの制約
エンジンの実行中は、デバッグポートが開いたままになります。
このコンピューターからしか接続できませんが、エンジンが動いている間は、このコンピューター上のどのプログラムにも開かれており、到達できるものなら何でもそれらのページを操作できます。セッションはポートが開かれるたびに警告し、漠然と触れるのではなくポート番号を明記します。共有マシンや信頼できないマシンでは、何も開かないスイッチを使ってください。
昇格して動いているアプリには届きません。
昇格したアプリがホストするエンジンは、セッションが設定する変数を無視するため、そのページは実際の時計のままです。これはエンジン自身の規則であって設定ではなく、外側から回避する方法はありません。
このようなセッションは PARTIAL と報告します。それが正直な答えです。
エンジンのヘルパープロセスと、レンダラー自身のネイティブな時刻呼び出しは、実際の時計のままです。ページはセッションの時計に乗り、そのファミリーの残りは乗らないので、判定は一部有効となり、切り上げて合格にするのではなく、取り残されたものを名指しします。
さらに 2 つ、小さなことをはっきり述べておきます。ページはセッションのタイムゾーンを固定オフセットとして読むため、Intl はそれを都市ではなく GMT+02:00 のようなオフセットで呼びます。そして、セッションがページに到達する前にスケジュールされたタイマーは、純粋な Chromium のセッションと同様、元のペースを保ちます。何も起きなかったと誤解させないよう、セッションは警告します。
エンジンがレジストリのブラウザー引数ポリシーで構成されている場合、セッションの間はセッションの変数が優先され、レポートがそのことを伝えます。そこで設定したデバッグポートは適用されなかったはずだからです。
どれほどテストされているか
実験的です。ここでも他と同じ決まった意味があります。想定した対象では動作する、広範にはテストされていない、そして信頼できる情報源は、このページではなく内蔵の監査である、ということです。自動化されたテスト一式ではなく、64 ビット Windows 上の WebView2 ホストと Qt WebEngine ホストで手作業により測定しました。それらの実行では、ページはセッションの年をセッションのペースで読み、ジャンプにも追従しました。
32 ビット Windows には、あとで気づくより知っておいたほうがよい癖があります。WebView2 のランタイムは、ホストするアプリが 32 ビットであっても 64 ビットなので、32 ビットのセッションはエンジンのプロセスやその役割を名指しできません。ページへのチャネルは引き続き動作します。レポートは、特定できなかったものについてやや具体性に欠けるだけで、2 つのどちらなのかは明記します。