Windows11をようやく使い始めた話(電源プランについて)

# はじめに

こんにちわ、突然ですが、Windows11 へ、ようやく移行をはじめしました！

個人的にWindows10から移行できなかった理由に、以下の電源モードを重宝していたのが大きな理由です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3509469/4fd80492-3897-392c-435d-8dd81e9fee69.png)

# 電源モードとは？

タスクバーのスライダを操作することで、以下のような効果を得ることができるOSの機能です。

## 最大のバッテリー残量
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3509469/8a4015c3-3387-e9bd-c6bf-18798e0ce8bd.png)
* (パフォーマンスを落として) バッテリー駆動時間を重視する
    * テキストベースの作業の時などに使用
    * **バッテリ稼働時間を延ばすことができる！**

## 最も高いパフォーマンス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3509469/195b8370-d3c7-2aa9-4983-fca62dd64265.png)
* (バッテリ稼働時間を短くして) パフォーマンスを重視する
    * プログラムをビルドするときなどに使用
    * **パフォーマンスを向上させることができる**

こまめに切り替えることで、バッテリの稼働時間表示が明らかに変わるうえに、ワンタッチで手間もかからないため、使用頻度が高い機能でした。

# ところが・・・

Windows11になってからは、「設定」のなかに統合されてしまったため、ワンタッチで切り替えることができなくなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3509469/ec3b56f5-bb37-86d5-8e21-254dab341884.png)

そのため、過去にもWindows11にアップグレードしたことはあったのですが、この切り替えが個人的にとても不便で、Windows10に戻してしまっていました。

# Windows11でもワンタッチで電源プランを切り替えたい！

実際の動作をみてもらうのが一番わかりやすいかと思いますが、、、
ワンタッチで、この電源モードを切り替える(だけ🤣)のツールが出来上がりました。

![252155966-801ac9e5-24d2-4136-9a8b-1b2feb56f581.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3509469/4939720d-0b4c-a29b-859b-2a50ba08d26a.gif)

使い方は、すごくシンプルですが、画面上に表示されている
  * より良いバッテリ・トップクラスの電力効率
  * 高パフォーマンス・バランス
  * 最も高いパフォーマンス・最適なパフォーマンス

ボタンをクリックするだけで、OSの電源プランが切り替わります。

設定ファイルを変更することで、タスクバーの通知領域に常駐して、ワンタッチで呼び出すこともできます！

![Animation2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3509469/aa2fb27f-11a1-aa4a-cb06-a4b19d81b81b.gif)

# ツールの公開先

GitHubにて公開していますので、ピンときた方はお使いください！

https://github.com/tarohanako-com/PowerSchemeUtility/

インストールは不要で、ZIPファイル内に一式格納しています。
https://github.com/tarohanako-com/PowerSchemeUtility/releases

Zipファイルを解凍したら、PowerSchemeUtility.exeを実行してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3509469/a20d5a66-2434-c326-ea26-af13a6d52f42.png)

なお、お使いにあたり、以下のパッケージ・ランタイムが必要です。
もし、エラーで起動しない場合などは、導入してください。

* Visual Studio 2015-2022 再頒布可能パッケージ
https://aka.ms/vs/17/release/vc_redist.x86.exe
https://aka.ms/vs/17/release/vc_redist.x64.exe

* .NET Framework 4.8 ランタイム
https://dotnet.microsoft.com/ja-jp/download/dotnet-framework/thank-you/net48-web-installer

また、レジストリへの書き込み等も行っていないので、アンインストール時は、フォルダごと削除するだけです。

# 技術的なおはなし

以下は、このツールの技術的な仕組みです。

## アプリケーションの構成について

本ツールは、以下のプロセス構成で実現しています。

* UI関連プロセス: PowerSchemeUtility.exe
* 電源プラン切替プロセス: PowerProfCmd.exe

具体的には以下の役割となっています。

* UI関連プロセス: PowerSchemeUtility.exe
    * 画面を表示する
    * 常駐アプリケーションとしてOSに常駐して、タスクバーの通知領域にアイコンを生成する
    * クリックされた際に、電源プラン切替プロセス(PowerProfCmd.exe)を呼び出す
    * 定期的に電源プラン切替プロセス(PowerProfCmd.exe)を呼び出して、現在の電源プランを表示する

* 電源プラン切替プロセス: PowerProfCmd.exe
    * 呼び出された引数によって以下の処理を行う
        * 現在OSに設定されている電源プランを返却する
        * 指定された電源プランをOSに設定する

## UI関連プロセス: PowerSchemeUtility.exe

UI関連プロセスは、C#(WPF)で実装しています。

アプリケーションのフットプリントを小さくする(いろいろなDLLを不要にする)ためと、今回は必要な実装が比較的簡単なので、MVVMフレームワークは用いずに、コードビハインドで実装しています。

主な役割と、処理は以下の通りです。

* 電源プランのボタンがクリックされたとき
    * 電源プラン切替プロセス(PowerProfCmd.exe)を、/SetActiveSchemeIdを実行時引数として呼び出す

* 定期間隔タイマーで現在のOSの電源プランを取得する
    * 電源プラン切替プロセス(PowerProfCmd.exe)を、/GetActiveSchemeTextを実行時引数として呼び出す
    * 電源プランの名称が標準出力に返るので、その名称をラベルに表示する
    * ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3509469/60852ac4-3f5d-a95f-96c1-8e8afde9100c.png)

## 電源プラン切替プロセス: PowerProfCmd.exe

電源プラン切替プロセスは、OSの電源プランを取得・設定するにあたり、Win32APIを実行する必要があるため、C++で実装しています。

電源関係のWin32APIは、powrprof.hにありました。
電源プランの切り替えは、電源プランにGUIDが定義されており、そのGUIDを指定する形でした。

なお、呼び出すGUIDは以下を参考にしました。
https://learn.microsoft.com/ja-jp/windows-hardware/customize/desktop/customize-power-slider#configure-performance-and-power-settings

主な役割と、処理は以下の通りです。

* 実行時引数に/SetActiveSchemeIdが指定された
    * 指定された電源プランに該当するGUIDを取得する
    * 取得したGUIDをPowerSetActiveOverlayScheme()で設定する

* 実行時引数に/GetActiveSchemeTextが指定された
    * PowerGetActualOverlayScheme()を使用して現在の電源プランのGUIDを取得する
    * 取得した電源プランのGUIDに該当する電源プランの名称を標準出力へ出力する。

## 余談 - powrprof.hについて

使用しているWin32APIのヘッダーファイル「powrprof.h」を、「pow**e**rprof.h」だと思い込んでおり、ファイルが見つからずめちゃくちゃハマりました・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3509469/be519e91-3e2c-19e0-c369-51663c8ed3b2.png)