ずんだもん「Windowsのライト/ダークテーマをワンクリック切り替えするミニアプリを作るのだ」


# はじめに

**ずんだもん**「きりたん、Windows11ってダークモードがあるの便利なのだな。でもテーマ切り替え、毎回設定ウインドウを開くの地味にめんどいのだ～😭」

**きりたん**「それならPowerShellスクリプトをEXE化して、スタートメニューから一発で切り替えられるようにしましょうか。」

<table>
  <tr>
    <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/c0f938e8-bc8c-40c7-8ba6-db76fe6fe150.png" alt="Image 1" width="150"></td>
    <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/eb5db776-7bdd-4908-83ee-cd120627b4bc.png" alt="Image 2" width="160"></td>
  </tr>
</table>


# どんなことをするの？

**ずんだもん**「どんな流れでやるのか教えてほしいのだ！」

**きりたん**「こんなかんじですよ。」

::: note
1. テーマ切り替え用のPowerShellスクリプトを作る
    
2. それをps2exeでEXE化する
    
3. スタートメニューにショートカットを自動で作る

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/ac0cb5ff-0781-49ef-920d-f39a36a37505.png)

:::
    

# スクリプト全文

**きりたん**「これが全自動スクリプト！管理者権限で実行してくださいね」

```Create-Win11Theme-SwitcherApp.ps1
# -----------------------------------------------------------
# このスクリプトはWindowsのライト/ダークテーマを切り替えるEXEを自動生成し、
# スタートメニューにショートカットを作成します。
#
# 実行には管理者権限が必要です。
# -----------------------------------------------------------

# 説明文をシアン色で表示
$description = @"
このスクリプトはWindowsのライト/ダークテーマを切り替えるEXEを自動生成し、
スタートメニューにショートカットを作成します。

実行には管理者権限が必要です。
"@
Write-Host $description -ForegroundColor Cyan

try {
    # ユーザーのドキュメントフォルダを取得
    $documents = [Environment]::GetFolderPath([Environment+SpecialFolder]::MyDocuments)
    $ps1Path = Join-Path $documents "ThemeSwitcher.ps1"
    $exePath = Join-Path $documents "ThemeSwitcher.exe"
    $shortcutPath = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\ThemeSwitcher.lnk"

    # ps2exeの存在を確認し、なければ対話式でインストール
    if (-not (Get-Command ps2exe -ErrorAction SilentlyContinue)) {
        $answer = Read-Host "ps2exeが見つかりません。インストールしますか？ (y/n)"
        if ($answer -eq 'y' -or $answer -eq 'Y') {
            Write-Host "ps2exeをインストールしています..." -ForegroundColor Cyan
            Install-Module -Name ps2exe -Force -Scope CurrentUser
        } else {
            Write-Host "ps2exeのインストールがキャンセルされたため、スクリプトを終了します。" -ForegroundColor Red
            exit
        }
    } else {
        Write-Host "ps2exeは既にインストールされています。" -ForegroundColor Green
    }

    # テーマ切り替え用のPowerShellスクリプトを作成
    $scriptContent = @'
$currentTheme = Get-ItemPropertyValue -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name AppsUseLightTheme
Set-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name AppsUseLightTheme -Value (1 - $currentTheme) -Type DWord -Force
Set-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name SystemUsesLightTheme -Value (1 - $currentTheme) -Type DWord -Force
Stop-Process -Name explorer -Force
Start-Process explorer.exe -WindowStyle Hidden
'@
    $scriptContent | Set-Content -Encoding UTF8 $ps1Path

    # ps1ファイルをEXEに変換
    Write-Host "PowerShellスクリプトをEXEに変換中..." -ForegroundColor Cyan
    ps2exe $ps1Path $exePath -noConsole

    # 変換後のps1ファイルを自動削除
    if (Test-Path $ps1Path) {
        Remove-Item -Path $ps1Path -Force
        Write-Host "一時的に作成したps1ファイルを削除しました。" -ForegroundColor Green
    }

    # スタートメニューにショートカットを作成
    $ws = New-Object -ComObject WScript.Shell
    $sc = $ws.CreateShortcut($shortcutPath)
    $sc.TargetPath = $exePath
    $sc.WorkingDirectory = $documents
    $sc.Save()
    Write-Host "スタートメニューにショートカットを作成しました。" -ForegroundColor Green

    Write-Host "すべて正常に完了しました！" -ForegroundColor Green
}
catch {
    # エラー発生時はウィンドウを閉じず、詳細なメッセージを表示
    Write-Host "エラーが発生しました：" -ForegroundColor Red
    Write-Host $_.Exception.Message -ForegroundColor Red
    Write-Host "処理を中断します。" -ForegroundColor Red
}


```

# 使い方

<table>
  <tr>
    <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/c0f938e8-bc8c-40c7-8ba6-db76fe6fe150.png" alt="Image 1" width="150"></td>
    <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/eb5db776-7bdd-4908-83ee-cd120627b4bc.png" alt="Image 2" width="160"></td>
  </tr>
</table>

**ずんだもん**「ありがとうなのだ。でも、これってどうやって使えばいいのだ？」

**きりたん**「こんな感じになりますよ。」

::: note

1. 上のスクリプトを `CreateThemeSwitcher.ps1` などの名前で保存
    
2. PowerShellを管理者権限で開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/19435068-984f-4976-b286-05126f1cf557.png)

3 . スクリプトが実行される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/48ae2155-3dd9-412f-b0a4-ea8f1d24d2a1.png)

:::


**きりたん**「これでスタートメニューの「すべてのアプリ」に『ThemeSwitcher』が追加されますよ。」

# アイコンの変更

**きりたん**「お好みでアイコンを変更してくださいね。」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/5a5e82e7-92d2-4b51-9a1a-25447dde9dfc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/09027993-a793-4d2d-851d-0f4a1329ace4.png)

# 動作イメージ

**ずんだもん**「おお！アプリをクリックするだけでダークモードになったのだ！」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/ac0cb5ff-0781-49ef-920d-f39a36a37505.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/f28fea05-e763-4160-ac52-771769a0200a.png)


# 注意点


<table>
  <tr>
    <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/c0f938e8-bc8c-40c7-8ba6-db76fe6fe150.png" alt="Image 1" width="150"></td>
    <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/eb5db776-7bdd-4908-83ee-cd120627b4bc.png" alt="Image 2" width="160"></td>
  </tr>
</table>


**ずんだもん**「もしうまくいかないときはどうするのだ？」

**きりたん**「以下のポイントに気を付けてくださいね。」

::: note warn
- ps2exeのインストール時に警告が出たら「y」などで承認してください。
    
- スタートメニューへのショートカット作成には管理者権限が必要。
    
- テーマ切り替え後、explorer.exeが再起動されるけど、たまにエクスプローラーのウィンドウが開くことがあるのは仕様ですよ。
:::

# まとめ

**ずんだもん**「これで毎日気分に合わせてテーマを変えられるのだ！」

**きりたん**「みんなも自分好みにカスタマイズしてみてくださいね。」

# 休憩室にて

<table>
  <tr>
    <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/c0f938e8-bc8c-40c7-8ba6-db76fe6fe150.png" alt="Image 1" width="150"></td>
    <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/eb5db776-7bdd-4908-83ee-cd120627b4bc.png" alt="Image 2" width="160"></td>
  </tr>
</table>

**ずんだもん**：「ねえきりたん、このスクリプトをきりたんに直接実行したら、きりたんの性格も『ライト』になったりするのだ？」

**きりたん**：「なりません。たぶんエラーを吐いて応答しなくなります。」

**ずんだもん**：「きりたん、もしかして“ダークモード”固定なのだ！？」

**きりたん**「違います。私は"デバッグモード"で動いてるんです。」

**ずんだもん**「デバッグモード？それってバグを直してくれるのだ？」

**きりたん**「そう、仕様です。ツンデレ機能も標準搭載ですから。」

**ずんだもん**「おお！マルチプロセスなのだ！ぼくも負けていないのだ！マルチにずんだ餅を食べながら、ずんだ餅のことを考えて、ずんだ餅の夢を見ているのだ！」

**きりたん**「それ、全部同じプロセスです...。」

## 利用キャラクター

- ずんだもん：[VOICEVOX:ずんだもん](https://voicevox.hiroshiba.jp/)

本記事で使用しているキャラクター画像の著作権は、それぞれの権利者に帰属します。
非商用目的での利用に基づき掲載しています。

# リンク集
https://qiita.com/denkiuo604/items/c55dc2bc34cdae9e35cf

https://qiita.com/sharu2920/items/495d510ee0355a4f9e6b

https://www.youtube.com/watch?v=o730kcgY2Bk