Windowsにはログオン時にアプリを実行する方法がいくつかあります。
- ログオンスクリプト(グループポリシー)
- スタートメニューのスタートアップ
- レジストリのRunキー
このうちログオンユーザーで実行されるものを計測します。
- ログオンスクリプト
- レジストリ(ユーザー)
- スタートアップ(全ユーザー)
- スタートアップ(ユーザー)
それぞれの起動時間を計ってみようと思います。Windows 11 24H2 Pro での確認結果です。
※今回の確認は一つの方法(スタートメニューのスタートアップなど)の中で複数ある場合の起動順序ではありません。
まず、実行されたら時間を出力するバッチファイルを作成します。
powershell.exe -Command "(Get-Date).ToString('HH:mm:ss.fff')" >> %~dp0%~n0.txt
この1行を記述して保存。ファイル名を変更して、計4個作成します。このバッチファイルを実行すると、バッチファイルと同じファイル名のtxtにミリ秒までの時間を出力します。
これを
| ログオンスクリプト | ローカルグループポリシー → ユーザーの構成 → Windows の設定 → スクリプト(ログオン/ログオフ) → ログオン |
| レジストリ(ユーザー) | HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run |
| スタートアップ(全ユーザー) | C:\ProgramData\Microsoft\Windows\Start Menu |
| スタートアップ(ユーザー) | C:\Users<ユーザー名>\AppData\Roaming\Microsoft\Windows\Start Menu |
で実行されるように登録します。ポリシーにはドメインのグループポリシーもありますが、今回はローカルグループポリシーのみ確認します。
パソコンを再起動して時間を確認します。イベントログサービスが起動した時間を0秒として自動ログオンした場合の計測です。
結果1
| ログオンスクリプト | 1:04:815 |
| レジストリ(ユーザー) | 2:35:409 |
| スタートアップ(全ユーザー) | 2:57:538 |
| スタートアップ(ユーザー) | 3:11.988 |
こういった順で動くようです。
Windowsのスタートアップは、起動時に遅延するように設定されています。 昔からのようですが、Windows 11 24H2 から特に顕著なようで体感でわかるとお聞きします。ログオンスクリプトと同じくらいのタイミングでデスクトップ画面が出たとすると、2分ほど遅延して実行されていることになります。
この遅延はレジストリで無効にすることができるようです。 なぜ遅延されているかを調べても、「性能の低いPCで起動時にリソース不足の発生を防ぐため」程度の情報しか出てきませんでした。この設定は性能の高いPCにも影響しています。 あまり問題ない場合もありますが、スタートアップで何かを実行する場合はとても気になることになります。
レジストリを変更してみます。 もちろん、OSの設定画面で変更できない変更を行うので自己責任です!
レジストリはこちら。Serialize キー(標準ではないので新規作成)にWaitForIdleState値を0で作成します。システムがアイドル状態になるまで待つというレジストリをOFF(0)にするようです。
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Serialize]
"WaitForIdleState"=dword:00000000
ではこれを設定して再起動します。
結果2
| レジストリ(ユーザー) | 1:01:082 |
| スタートアップ(全ユーザー) | 1:01.707 |
| スタートアップ(ユーザー) | 1:26:160 |
| ログオンスクリプト | 0:54:999 |
ログオンスクリプトにはあまり影響がなかったようですが、それ以外が速くなりました。そのため、ログオンスクリプトのほうが遅くなるという結果に。ログオンスクリプトは別で遅延設定があるようです。最後に実行されたスタートアップ(ユーザー)を比べると2分以上速くなっています。
速くなることは分かったので、ここからはさらに気になったことを確認します。WaitForIdleState を0にすると速くなりましたが、0以外だとどうなるのか。一般的には0と1(or 0以外)で切り替えることが多いので、1にしてみます。
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Serialize]
"WaitForIdleState"=dword:00000001
ではこれを設定して再起動します。
結果3
| ログオンスクリプト | 1:05:562 |
| レジストリ(ユーザー) | 2:22:746 |
| スタートアップ(全ユーザー) | 2:39:907 |
| スタートアップ(ユーザー) | 3:10.008 |
最初の何も設定していない【結果1】と順番も同じで2秒弱の差。途中多少時間の違いはあれど誤差の範囲でほぼ同じという感じです。
同じキーのレジストリに StartupDelayInMSec という値があるようなので、こちらも設定してみます。 MSec...おそらくミリ秒だと思われるので 60000ミリ秒=60秒 を設定します。16進数だと0xea60。
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Serialize]
"WaitForIdleState"=dword:00000000
"StartupDelayInMSec"=dword:0000ea60
ではこれを設定して再起動します。
結果4
| ログオンスクリプト | 1:25:355 |
| レジストリ(ユーザー) | 2:13:387 |
| スタートアップ(全ユーザー) | 2:22:134 |
| スタートアップ(ユーザー) | 2:23.208 |
ログオンスクリプトはこのレジストリに影響されないのはこれまでの検証の通りで、【結果2】と同じくらいの時間でした。
ログオンスクリプト以外は80秒くらい遅くなっています。設定したのは60秒ですが、この設定が効いていることはわかりました。
通常は設定することはないと思いますが、スタートアップを速くせずに遅延時間だけ設定してみます。
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Serialize]
"WaitForIdleState"=dword:00000001
"StartupDelayInMSec"=dword:0000ea60
ではこれを設定して再起動します。
結果5
| ログオンスクリプト | 0:59:058 |
| レジストリ(ユーザー) | 2:45:692 |
| スタートアップ(全ユーザー) | 3:44:067 |
| スタートアップ(ユーザー) | 5:08.064 |
【結果3】と比べると、レジストリに70秒、スタートアップ80秒、120秒と影響が出て遅くなりました。 設定値より多くばらつきもありましたが、StartupDelayInMSec で遅くできるということはわかりました。
まとめると以下のような確認結果になりました。
-
ログオンユーザーのスタートアップの実行順は
ログオンスクリプト
レジストリ(ユーザー)
スタートアップ(全ユーザー)
スタートアップ(ユーザー) -
スタートアップの遅延は、自己責任ですが以下のレジストリ設定で速くなる。
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Serialize]
"WaitForIdleState"=dword:00000000
- ログオンスクリプトには影響しない。
- 設定がない場合は、アイドル状態になるのを待ってからスタートアップが実行される。
- アイドル状態を待たずに実行する場合でも StartupDelayInMSec で遅延時間を設定できる。
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Serialize]
"WaitForIdleState"=dword:00000000
"StartupDelayInMSec"=dword:0000ea60

