2025-09-17 タスクバーの配置で TaskbarAl
が存在しない場合,中央揃いになることが判明し,記事およびスクリプトを修正。
はじめに
ようやく OS が Windows 11 になりました。今さらですが,先行ユーザーの皆さんの不満が分かるようになりました。具体的には下記になります。
- エクスプローラのコンテキストメニューの階層が深くなって使いにくい。※コレが一番
- エクスプローラの詳細表示で行間隔が空き過ぎて間延び感がある。
- ファイルの拡張子を常に表示させたい。
- タスクバーが中央揃いなのは違和感がある。
- タスクバーの検索ボックスを消したい。※コレは Windows 10 の頃からある
- ウィンドウがアクティブ時にタイトルバーの色をアクセントカラーにしたい。
※コレも Windows 10 の頃からあるが設定方法が変わって分かりにくい - ウィンドウズターミナルがデフォルトになったが,コマンドプロンプトに戻したい。
※コレは少数派かもしれない
おかげ様でどれもレジストリを弄れば良いということが分かっています。一度書き換えれば良いので,レジストリエディタを使って直接書き換えても良いのですが,この種のレジストリ設定は Windows アップデートしたら元に戻ってしまうことが多かったので,PowerShel スクリプトとして残すことにしました。
なぜ PowerShell スクリプトを採用したのか?
Windows に備え付けのスクリプト言語だけで実現しようとすると以下の三つが選択肢になるでしょう。
- バッチファイル
- Windows Script Host(WSH)
- PowerShell スクリプト
この中で PowerShell スクリプトを採用したのは以下の理由に依ります。
- 取り扱うレジストリが 10 個近くなると構造体のようなデータ構造でまとめて綺麗に管理したくなります。WSH は JScript を選択すれば可能ですが,バッチファイルではほぼ無理でしょう。
- PowerShell はレジストリを操作するための機能がとても充実しています。バッチファイルでは
reg
コマンド,WSH ではWshShell
オブジェクトで提供されているメソッドを利用することになりますが,いずれも所望するレジストリキーが存在するかどうかをチェックする手段すら無いのです。失敗した際のエラー処理を用いれば可能ですが,直感的ではありません。 - PowerShell はカラー表示が簡単にできます。バッチファイルは VT100 互換エスケープシーケンスを使えば可能ですが,WSH は何故かエスケープシーケンスが通りません。
レジストリ情報
表1 エクスプローラのコンテキストメニュー | |
---|---|
キー | HKCU:\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32 |
値名 | 空の値名(既定値) |
型名 | String |
値 | キーが存在しない,または値が未設定の場合:新しいメニュー キーが存在し,何らかの値が設定されている場合:旧来のメニュー ※変更後,エクスプローラを再起動する必要がある |
表2 エクスプローラのコンパクト表示 | |
---|---|
キー | HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced |
値名 | UseCompactMode |
型名 | DWord |
値 |
0 :非コンパクト表示1 :コンパクト表示※値名が存在しない場合,非コンパクト表示とみなす。 |
表3 ファイルの拡張子の非表示 | |
---|---|
キー | HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced |
値名 | HideFileExt |
型名 | DWord |
値 |
0 : 表示1 : 非表示※変更後,エクスプローラを再起動する必要がある。 |
表4 タスクバーの位置 | |
---|---|
キー | HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced |
値名 | TaskbarAl |
型名 | DWord |
値 |
0 : 左揃え1 : 中央揃え※値名が存在しない場合,中央揃えとみなす。 |
表5 タスクバーの検索ボックス | |
---|---|
キー | HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Search |
値名 | SearchboxTaskbarMode |
型名 | DWord |
値 |
0 : 非表示1 : アイコン表示2 : 検索ボックス表示 |
表6 ウィンドウがアクティブ時のタイトルバーの色 | |
---|---|
キー | HKCU:\SOFTWARE\Microsoft\Windows\DWM |
値名 | ColorPrevalence |
型名 | DWord |
値 |
0 : タイトルバーとウィンドウの罫線にアクセントカラーを表示しない1 : タイトルバーとウィンドウの罫線にアクセントカラーを表示する※環境によっては変更後,DWM を再起動する必要がある。 |
表7 コンソールホスト | |
---|---|
キー | HKCU:\Console\%%Startup |
値名 | DelegationConsole |
型名 | String |
値 |
{00000000-0000-0000-0000-000000000000} : 自動選択※{B23D10C0-E52E-411E-9D5B-C09FDF709C7D} : Windows Console Host{2EACA947-7F5F-4CFA-BA87-8F7FBEEFBE69} : Windows Terminal※使用可能な場合は Windows Terminal |
表8 ターミナル | |
---|---|
キー | HKCU:\Console\%%Startup |
値名 | DelegationTerminal |
型名 | String |
値 |
{00000000-0000-0000-0000-000000000000} : 自動選択※{B23D10C0-E52E-411E-9D5B-C09FDF709C7D} : Windows Console Host{E12CFF52-A866-4C77-9A90-F570A7AA2C6B} : Windows Terminal※使用可能な場合は Windows Terminal |
表9 エスケープシーケンス | |
---|---|
キー | HKCU:\Console |
値名 | VirtualTerminalLevel |
型名 | DWord |
値 |
0 : エスケープシーケンス無効1 : エスケープシーケンス有効※値名が存在しない場合,エスケープシーケンス無効とみなす。 レジストリ変更後,コマンドプロンプトを再起動する必要がある。 |
レジストリの変更方法
レジストリの状態
以下の四種類に分類しました。筆者オリジナルの分類です。
-
#NO-KEY
:所望のキーが存在しない場合 -
#KEY-ONLY
:所望のキーは存在するが,値名が必要ない場合 -
#NO-VAL
:所望のキーは存在するが,所望の値名が存在しない場合 -
その他
:上記以外,すなわち所望のキーおよび値名が存在する場合
レジストリの変更マップ
レジストリの変更マップを表1に示します。レジストリの状態は四種類あるものとして,現在値と更新後の組み合わせは $4^2 = 16$ 通り考えられますが,本ツールではこのうち五つの遷移のみ考えます。なお,記号の意味は下記の通りです。
-
:同一状態なのでレジストリの変更不要,×
:状態変更不可(エラー)
現在値 | |||||
---|---|---|---|---|---|
#NO-KEY |
#KEY-ONLY |
#NO-VAL |
その他 |
||
更新後 | #NO-KEY |
- | キーの削除 | × | × |
#KEY-ONLY |
キーの追加 | - | × | × | |
#NO-VAL |
× | × | - |
値の変更 |
|
その他 |
× | × |
値の変更 |
値の変更 |
このうち #NO-VAL
→ その他
の遷移については,値名を追加する手段と値を変更する手段が同一(いずれも Set-ItemProperty
を利用する)ため値の変更として扱います。
また,その他
→ #NO-VAL
の遷移については(本記事で取り扱うレジストリに限り)値名を削除する必要がなく,値を 0 にすれば削除と同じ扱いになるので値の変更として扱います。
データ構造
本スクリプトのデータ構造を示します。
メンバ名 | 型 | 内容 |
---|---|---|
key |
文字列 | レジストリのキー名 必須 |
name |
文字列または $null
|
レジストリの値名 存在しない場合は $null
|
type |
文字列または $null
|
レジストリの型,Dword , String など存在しない場合は $null
|
label |
文字列 | レジストリの説明 必須 |
table |
- | 値オブジェクトの配列 必須 |
value |
数値または $null
|
オプションで指定する値,0 以上の整数 未指定の場合は $null
|
reboot |
真偽値 | Explorer 再起動の要否 必須 |
値オブジェクトの各メンバーを示します。
メンバー | 型 | 内容 |
---|---|---|
alt |
文字列または $null
|
値の別名 特殊ワード: #NO-KEY ,#KEY-ONLY ,#NO-VAL もしくは設定する文字列,存在しない場合は $null
|
msg |
文字列 | 値の説明 必須 |
レジストリの操作方法
PowerShell によるレジストリの操作方法については記事8が有用です。値名の存在チェック方法について,B案は値が $null
の場合も許容するため採用しました。
- キーの存在チェック
if(Test-Path -LiteralPath "キー名") { # キーが祖納するときの処理 }
- キーを新規追加
New-Item "キー名" -Force | Out-Null
- キーを削除
Remove-Item -LiteralPath "キー名"
- 値名の存在チェック(A案)
$item = Get-ItemProperty -LiteralPath "キー名" if($item."値名" -ne $null) { # 値名が存在するときの処理 }
- 値名の存在チェック(B案)※本記事で採用
$item = Get-ItemProperty -LiteralPath "キー名" if($item.PSobject.Properties.Match("値名").Count -gt 0) { # 値名が存在するときの処理 }
- 値名を追加 ※空の値名(既定値)を追加
New-ItemProperty -LiteralPath "キー名" -Name '(default)' | Out-Null
- 値名を削除 ※本記事では使用しません
Remove-ItemProperty -LiteralPath "キー名" -Name "値名"
- 値を取得
$item = Get-ItemProperty -LiteralPath "キー名" $data = $item."値名"
- 値を変更 ※新規追加の場合も同様
Set-ItemProperty -LiteralPath "キー名" -Name "値名" -Type "型名" -Value "データ"
OSのバージョン情報
レジストリ操作は危険のため,念のため OS のバージョンチェックを行うようにしました。
Windows 11 って Windows 10 とはバージョン番号 10.0
まで同じで,ビルド番号だけが異なるんですね。Windows 11 が先行してビルド番号 22000
を取得してしまったため,Windows 10 のほうはそれを超えないようにビルド番号を急に小刻みにした感じです910。
ビルド番号が 22000
以上であれば Windows 11 と判断することにしました。
OS | バージョン | ビルド番号 |
---|---|---|
Windows 10 | 1507 | 10240 |
1511 | 10586 | |
1607 | 14393 | |
1703 | 15063 | |
1709 | 16299 | |
1803 | 17134 | |
1809 | 17763 | |
1903 (19H1) | 18362 | |
1909 (19H2) | 18363 | |
2004 (20H1) | 19041 | |
20H2 (20H2) | 19042 | |
21H1 | 19043 | |
21H2 | 19044 | |
22H2 | 19045 | |
Windows 11 | 21H2 | 22000 |
22H2 | 22621 | |
23H2 | 22631 | |
24H2 | 26100 |
ソースコード
ソースコードはコチラ ※300行弱あります
Set-StrictMode -Version Latest
#-------------------------------------------------------------------------------
# グローバル変数
#-------------------------------------------------------------------------------
$taskbar = @{
key = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced'
name = 'TaskbarAl'
type = 'DWord'
label = 'タスクバーの配置'
table = @(
@{ alt = $null; msg = '左揃え' }
@{ alt = '#NO-VAL'; msg = '中央揃え' }
)
value = $null
reboot = $false
}
$compact = @{
key = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced'
name = 'UseCompactMode'
type = 'DWord'
label = 'エクスプローラ'
table = @(
@{ alt = '#NO-VAL'; msg = '非コンパクト表示' }
@{ alt = $null; msg = 'コンパクト表示' }
)
value = $null
reboot = $false
}
$hidefileext = @{
key = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced'
name = 'HideFileExt'
type = 'DWord'
label = 'ファイルの拡張子'
table = @(
@{ alt = $null; msg = '表示' }
@{ alt = $null; msg = '非表示' }
)
value = $null
reboot = $true
}
$contextmenu = @{
key = 'HKCU:\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32'
name = $null
type = $null
label = 'コンテキストメニュー'
table = @(
@{ alt = '#KEY-ONLY'; msg = '旧来のスタイル' }
@{ alt = '#NO-KEY'; msg = '新しいスタイル' }
)
value = $null
reboot = $true
}
$searchbox = @{
key = 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Search'
name = 'SearchboxTaskbarMode'
type = 'DWord'
label = '検索ボックス'
table = @(
@{ alt = $null; msg = '非表示' }
@{ alt = $null; msg = 'アイコン表示' }
@{ alt = $null; msg = 'ボックス表示' }
)
value = $null
reboot = $false
}
$titlebar = @{
key = 'HKCU:\SOFTWARE\Microsoft\Windows\DWM'
name = 'ColorPrevalence'
type = 'DWord'
label = 'タイトルバーの色'
table = @(
@{ alt = $null; msg = 'デフォルト' }
@{ alt = $null; msg = 'アクセントカラー' }
)
value = $null
reboot = $false
}
$console = @{
key = 'HKCU:\Console\%%Startup'
name = 'DelegationConsole'
type = 'String'
label = 'コンソール'
table = @(
@{ alt = '{00000000-0000-0000-0000-000000000000}'; msg = 'デフォルト' }
@{ alt = '{B23D10C0-E52E-411E-9D5B-C09FDF709C7D}'; msg = 'コンソールホスト' }
@{ alt = '{2EACA947-7F5F-4CFA-BA87-8F7FBEEFBE69}'; msg = 'ターミナル' }
)
value = $null
reboot = $false
}
$terminal = @{
key = 'HKCU:\Console\%%Startup'
name = 'DelegationTerminal'
type = 'String'
label = 'ターミナル'
table = @(
@{ alt = '{00000000-0000-0000-0000-000000000000}'; msg = 'デフォルト' }
@{ alt = '{B23D10C0-E52E-411E-9D5B-C09FDF709C7D}'; msg = 'コンソールホスト' }
@{ alt = '{E12CFF52-A866-4C77-9A90-F570A7AA2C6B}'; msg = 'ターミナル' }
)
value = $null
reboot = $false
}
$escape = @{
key = 'HKCU:\Console'
name = 'VirtualTerminalLevel'
type = 'DWord'
label = 'エスケープシーケンス'
table = @(
@{ alt = '#NO-VAL'; msg = '無効' }
@{ alt = $null; msg = '有効' }
)
value = $null
reboot = $false
}
$request = $false
$reboot = $false
#-------------------------------------------------------------------------------
# ヘルプメッセージ
#-------------------------------------------------------------------------------
function Usage {
Write-Host 'レジストリを書き換えて Windows 11 のデスクトップ設定を変更します。'
Write-Host ''
Write-Host 'WIN11REG(.PS1) (コマンド) ...'
Write-Host ''
Write-Host '<コマンド一覧>'
Write-Host ''
Write-Host ' TASKBAR:(n) タスクバーの配置を変更します。'
Write-Host ' (0:左揃え, 1:中央揃え)'
Write-Host ' COMPACT:(n) エクスプローラーのコンパクト表示を変更します。'
Write-Host ' (0:非コンパクト表示, 1:コンパクト表示)'
Write-Host 'HIDEFILEEXT:(n) ファイルの拡張子表示を変更します。'
Write-Host ' (0:表示, 1:非表示)'
Write-Host 'CONTEXTMENU:(n) コンテキストメニューのスタイルを変更します。'
Write-Host ' (0:旧来のスタイル, 1:新しいスタイル)'
Write-Host ' SEARCHBOX:(n) 検索ボックスの表示を変更します。'
Write-Host ' (0:非表示, 1:アイコン表示, 2:ボックス表示)'
Write-Host ' TITLEBAR:(n) タイトルバーの色を変更します。'
Write-Host ' (0:デフォルト, 1:アクセントカラー)'
Write-Host ' CONSOLE:(n) コンソールを変更します。'
Write-Host ' (0:デフォルト, 1:コンソールホスト, 2:ターミナル)'
Write-Host ' TERMINAL:(n) ターミナルを変更します。'
Write-Host ' (0:デフォルト, 1:コンソールホスト, 2:ターミナル)'
Write-Host ' ESCAPE:(n) エスケープシーケンスを変更します。'
Write-Host ' (0:無効, 1:有効)'
Write-Host ' REBOOT 必要に応じてエクスプローラを再起動します。'
Exit -1
}
#-------------------------------------------------------------------------------
# コマンドライン解析
#-------------------------------------------------------------------------------
function Get-CommandLine {
$args = $SCRIPT:ARGS
if($args.Count -eq 0) { Return }
foreach($arg in $args) {
if($arg -match 'TASKBAR:(\d+)') { $SCRIPT:taskbar.value = $Matches[1] }
elseif($arg -match 'COMPACT:(\d+)') { $SCRIPT:compact.value = $Matches[1] }
elseif($arg -match 'HIDEFILEEXT:(\d+)') { $SCRIPT:hidefileext.value = $Matches[1] }
elseif($arg -match 'CONTEXTMENU:(\d+)') { $SCRIPT:contextmenu.value = $Matches[1] }
elseif($arg -match 'SEARCHBOX:(\d+)') { $SCRIPT:searchbox.value = $Matches[1] }
elseif($arg -match 'TITLEBAR:(\d+)') { $SCRIPT:titlebar.value = $Matches[1] }
elseif($arg -match 'CONSOLE:(\d+)') { $SCRIPT:console.value = $Matches[1] }
elseif($arg -match 'TERMINAL:(\d+)') { $SCRIPT:terminal.value = $Matches[1] }
elseif($arg -match 'ESCAPE:(\d+)') { $SCRIPT:escape.value = $Matches[1] }
elseif($arg -eq 'REBOOT' ) { $SCRIPT:reboot = $true }
else {
Usage
}
}
}
#-------------------------------------------------------------------------------
# OS のバージョンチェック
#-------------------------------------------------------------------------------
function Check-Version {
$ver = $PSVersionTable.BuildVersion
if($ver.Major -eq 10 -and $ver.Minor -eq 0 -and $ver.Build -ge 22000) {
Return
} else {
Write-Host -ForegroundColor red 'Windows 11 ではありません!'
Exit -1
}
}
#-------------------------------------------------------------------------------
# レジストリのチェック
#-------------------------------------------------------------------------------
function Check-Registry($dat) {
#---------------------------------------------------------------------------
# レジストリの取得
#---------------------------------------------------------------------------
if(Test-Path -LiteralPath $dat.key) {
$item = Get-ItemProperty -LiteralPath $dat.key
if($dat.name -eq $null) {
$prev = '#KEY-ONLY'
} elseif($item.PSobject.Properties.Match($dat.name).Count -gt 0) {
$prev = $item."$($dat.name)"
} else {
$prev = '#NO-VAL'
}
} else {
$prev = '#NO-KEY'
}
#---------------------------------------------------------------------------
# ルックアップテーブルの検索
#---------------------------------------------------------------------------
for($i = 0; $i -lt $dat.table.length; $i++) {
if($prev -eq $i -or $prev -eq $dat.table[$i].alt) { Break }
}
if($i -ge $dat.table.length) {
Write-Host "レジストリ $($dat.key) の取得に失敗しました!"
Exit -1
}
Write-Host "現在の$($dat.label)は「$($dat.table[$i].msg)」です。"
if($dat.value -eq $null -or $dat.value -eq $i) { Return }
#---------------------------------------------------------------------------
# レジストリの更新
#---------------------------------------------------------------------------
$next = $dat.table[$dat.value].alt
if($next -eq $null) { $next = $dat.value }
$op = 'error'
switch($prev) {
'#KEY-ONLY' {
switch($next) {
'#KEY-ONLY' {}
'#NO-KEY' { $op = 'remove' }
'#NO-VAL' {}
default {}
}
}
'#NO-KEY' {
switch($next) {
'#KEY-ONLY' { $op = 'create' }
'#NO-KEY' {}
'#NO-VAL' {}
default {}
}
}
'#NO-VAL' {
switch($next) {
'#KEY-ONLY' {}
'#NO-KEY' {}
'#NO-VAL' {}
default { $op = 'update' }
}
}
default {
switch($next) {
'#KEY-ONLY' {}
'#NO-KEY' {}
'#NO-VAL' { $op = 'update' }
default { $op = 'update' }
}
}
}
switch($op) {
'remove' {
Remove-Item -LiteralPath $dat.key
}
'create' {
New-Item $dat.key -Force | Out-Null
New-ItemProperty -LiteralPath $dat.key -Name '(default)' | Out-Null
}
'update' {
Set-ItemProperty -LiteralPath $dat.key -Name $dat.name -Value $dat.value -Type $dat.type
}
default {
Write-Host 'レジストリの更新に失敗しました!'
Exit -1
}
}
Write-Host -ForegroundColor yellow " ⇒$($dat.label)を「$($dat.table[$dat.value].msg)」に変更しました。"
#---------------------------------------------------------------------------
# エクスプローラの再起動要求
#---------------------------------------------------------------------------
if($dat.reboot) { $SCRIPT:request = $true }
}
#-------------------------------------------------------------------------------
# コマンドライン解析
#-------------------------------------------------------------------------------
Get-CommandLine
#-------------------------------------------------------------------------------
# OS のバージョンチェック
#-------------------------------------------------------------------------------
Check-Version
#-------------------------------------------------------------------------------
# レジストリのチェック
#-------------------------------------------------------------------------------
Check-Registry $taskbar
Check-Registry $compact
Check-Registry $hidefileext
Check-Registry $contextmenu
Check-Registry $searchbox
Check-Registry $titlebar
Check-Registry $console
Check-Registry $terminal
Check-Registry $escape
#-------------------------------------------------------------------------------
# エクスプローラーの再起動
#-------------------------------------------------------------------------------
if($request) {
if($reboot) {
Write-Host -ForegroundColor 'yellow' 'エクスプローラを再起動します。'
Stop-Process -Name 'Explorer' -Force
} else {
Write-Host -ForegroundColor 'red' 'エクスプローラを再起動して下さい。'
}
}
実行画面
引数なしで実行した場合
引数なしで実行すると,レジストリを参照して現在の設定値を表示します。なお,OS のバージョンチェックは事前に行います。
Windows 10 で実行した場合
ちなみに Windows 10 で実行するとエラーになります。エラーメッセージは赤色 #e74856
で示します。
ヘルプメッセージ
存在しないオプションを指定するとエラー扱いとなり,ヘルプメッセージを表示します。OS のバージョンチェックは行いません。
レジストリを変更したとき
レジストリを変更したときは変更箇所を黄色 #f9f1a5
で示すようにしました。エクスプローラの再起動が必要な場合はメッセージを赤色 #e74856
で示します。
再起動オプションを指定したとき
再起動オプション reboot
を指定すると,エクスプローラを強制的に再起動します。開いていたフォルダ等が一斉に閉じられるので注意して下さい。
備考
タイトルバーの色については, PC によっては DWM を再起動しないとレジストリ変更が有効にならないケースがあるようです。そのような場合は下記のバッチファイルを管理者権限で実行して下さい。この際,DWM を利用したアプリが一斉に落ちてしまうので注意して下さい。
@echo off
openfiles > nul
if errorlevel 1 (
echo %~f0 は管理者権限で実行して下さい!!
pause
exit /b
)
taskkill /F /IM dwm.exe
echo dwm.exe を再起動しました。
pause
管理者権限まで使って dwm.exe を強制終了させるのはさすがに乱暴すぎると思っており,代替案を検討しています。