ゲーミングPCのLEDをC#で制御するⅡ　～AuraCreatorを併用し、画面ロック時のみ消灯～

# はじめに
「 [ゲーミングPCのLEDをC#で制御する](https://qiita.com/unasenohkoku/items/d926b2e9077430962b55 "ゲーミングPCのLEDをC#で制御する")」の続きになります。
今回も環境は下記です。
 - ASUS製マザボ
 - C#

# 今回の目的
「通常時はAuraCreatorで設定できる範囲の光り方でいいんだけど、特定の状況/タイミングで自由に光らせたい」という需要に応えます。
私は光るPCが好きですが、画面ロック(Win+Lで出来るアレです)中、つまり離席中にまで光っているのはなんとなく落ち着かないです。トイレの照明を消し忘れているような気分になります。そこで今回は
 - 画面ロック時にLEDを消灯
 - 画面ロックを解除したらLEDを点灯

という挙動を実現させます。

# ポイント1　画面ロック状態変更検知
言うまでもなく、「画面ロック」と「画面ロック解除」を検知できることが大前提です。
「[Windowsの画面ロックをC#で検知する](https://qiita.com/unasenohkoku/items/380e4fb4613b5abe96ea "Windowsの画面ロックをC#で検知する")」より、`SystemEvents.SessionSwitch`でキャッチします。

https://qiita.com/unasenohkoku/items/380e4fb4613b5abe96ea

# ポイント2　LED制御権の取得と解放
画面ロック解除後の点灯については、自分で点灯パターンをコーディングするのはめんどくさいのでAuraCreatorにやってもらいます。
前回の記事にも記載した通り、複数のプロセスが同時にLEDの制御権を持つことはできません。上手いこと制御権を譲渡してやる必要があります。
AuraCreatorへの制御権譲渡方法としては、以下の選択肢があります(自身とAuraCreator以外に、第三のLED制御プログラムがいる可能性は考慮しない)。

## [手法その1]　画面ロック状態監視とLED制御を別々のプロセスに分ける
制御権を持ったプロセスが正常終了した場合は勝手にAuraCreatorへ制御権が戻ります。
なので、画面ロック検知用プロセスからLED制御用のサブプロセスを走らせたり終了させたりすることで対応可能です。

やや搦め手的なアプローチとなり、コードも少し長くなります。何らかの要因により明確なメリットを見出せる場合を除き、後述の手法その2の方が無難だと思います。

## [手法その2]　`IAuraSdk2.ReleaseControl()`で解放する
` new AuraSdk() as IAuraSdk2`で生成されたインスタンスは、`ReleaseControl()`メソッドを持ちます。
これを呼び出すことで、プロセスを終了することなく明示的に制御権を解放することが可能です。

※`new AuraSdk()`だけで生成するインスタンスには存在しないメソッドです。

# コード全文

画面は要らないのでコンソールアプリケーションとしてプロジェクトを作成しました。
.NET Framework 4.7.2です。

```C#:Program.cs (.NET Framework 4.7.2)
using AuraServiceLib;
using Microsoft.Win32;

namespace LEDTurnOffWhenScreenLock {
    internal class Program {

        private static IAuraSdk2 sdk = new AuraSdk() as IAuraSdk2;

        static void Main(string[] args) {
            SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;

            //SystemEventsを待機し続ける
            for (; ; );
        }

        /// <summary>
        /// イベント処理用
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e) {

            switch (e.Reason) {
                case SessionSwitchReason.SessionLock:
                    //Console.WriteLine(DateTime.Now + "：画面ロック");

                    //LED制御権を取得
                    sdk.SwitchMode();

                    //LED消灯
                    setColorAllLED(0);
                    break;

                case SessionSwitchReason.SessionUnlock:
                    //Console.WriteLine(DateTime.Now + "：画面ロック解除");

                    //LED制御権を解放
                    sdk.ReleaseControl(0);
                    break;
            }
        }

        /// <summary>
        /// 色設定用の共通処理
        /// </summary>
        /// <param name="colorCode"></param>
        static private void setColorAllLED(uint colorCode) {
            IAuraSyncDeviceCollection devices = sdk.Enumerate(0);

            //全部のデバイス
            foreach (IAuraSyncDevice dev in devices) {
                //全部のLED
                foreach (IAuraRgbLight light in dev.Lights) {
                    //色を設定
                    light.Color = colorCode;
                }

                //反映
                dev.Apply();
            }
        }
    }
}


```
### `IAuraSdk2.ReleaseControl()`
引数にuint型の値を渡す必要がありますが、公式ドキュメントを見ると「0しか使えないよ」と書いてあります。将来的にはただ解放するのではなく譲渡先を指定できるようにするつもりなのかも……？

https://www.asus.com/microsite/aurareadydevportal/interface_aura_service_lib_1_1_i_aura_sdk2.html#a8b8fd82877d329cf09d8e81a0ed1a519

### 余談
イベント発生を無限ループで待たせていますが、これってリソースの観点ではどうなんでしょうね…………いや、LEDがピカピカするようなPCでそんな小さいことを気にするんじゃねえ！！

# 仕上げその1　画面非表示化
画面は要らないと言いながら、ばっちりコンソール画面が出ています。プロジェクト設定を変更しましょう。

プロパティを開いて……
![2022-12-18_21h29_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164419/b8c3f1c8-5474-e024-1c34-6ce42109b354.png)


出力の種類を[Windowsアプリケーション]に変更します。
![2022-12-18_21h31_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164419/10cf4e9f-77fc-3068-44c6-f7e4ee4cce81.png)

こうしておけば起動しても画面は表示されません。タスクマネージャからしか終了させられなくなりますが、基本的には一度起動したらもうあとは放置しておくタイプのアプリケーションなので問題無いでしょう(サービスアプリケーションとして作るべきだった……？)。

# 仕上げその2　自動起動
自動起動するようにしてあげます。

ビルドして生えてきたexeをお好みのフォルダに配置して、ショートカットを作ったらそいつを
`C:\Users\[ユーザー名]\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup`
に配置します。

Win+Rから飛ぶのが早いです。
![2022-12-18_21h44_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164419/7c390051-eb3f-4df9-22ab-555bff4a0544.png)

# おわり
以上です。
機能としては「いつかAuraCreatorが標準で対応してくれるかもな」というレベルなので、今日組んだプログラムはそのうちゴミと化すかもしれません。強く生きます。