C#にて統合環境フィルターの制御

# 概要
Windows10Iotの機能 統合環境フィルターでプロテクトをかけたPCについて、ブチギリを繰り返すと、オシロスコープ接続用のマネージャー（他社製）が立ち上がらなくなる現象が、発生した。
原因がわからないが、プロテクト解除　→　再起動　→　マネージャー起動　という形で治るのでアプリケーション(C#)にて現象を捉えたら　統合環境フィルターの設定を操作する事とした。

# 管理者権限アプリケーションの作成

#### マニフェストの作成
統合環境フィルターを操作する為には、管理者権限を持ったアプリケーションを作成する必要がある。
プロジェクトを作成後→「追加」→「新しい項目」→「アプリケーションマニフェスト　ファイル」　を作成する
下記の様にファイルを変更する。

```app.manifest 変更前
             <requestedExecutionLevel level="asInvoker" uiAccess="false" />
```
```app.manifest 変更後
             <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
```
asInvoker　アプリケーションは、それを開始したプロセスと同じアクセス許可レベルで実行

requireAdministrator　アプリケーションは、管理者のアクセス許可を使用して実行

#### ユーザーアカウント制御（UAC）
ユーザーアカウント制御を無効としないと、起動の度に確認画面が出力される為、無効とする
Windows10の場合、「コントロールパネル」→「ユーザーアカウント」→「ユーザーアカウント制御設定の変更」→「コンピュータに対する変更の通知タイミング」設定を「通知しない」


# WMI (Windows Management Instrumentation)の参照
統合環境フィルターの制御をWMIを介して実施する。
プロジェクトの参照に「System.Management」を追加する
　   「追加」→「参照」→「System.Management」

実装したコードが以下となる
# コード

```sample.cs

                ManagementScope scope = new ManagementScope(@"root\standardcimv2\embedded");
                ManagementClass UWFFilter = new ManagementClass(scope.Path.Path, "UWF_Filter", null);

                // foreach文で変数の型をManagementObject と指定しているのはキャストするため
                foreach (ManagementObject mo in UWFFilter.GetInstances())
                {
                    using (mo)
                    {
                        // プロテクト中か確認する
                        if (mo.GetPropertyValue("CurrentEnabled").ToString() == "True")
                        {
                                // プロテクト中
                                // 何か処理を記載

                                // アンプロテクト →　再起動
                                mo.InvokeMethod("Disable", null, null);
                                mo.InvokeMethod("RestartSystem", null, null);

                            }
                            else
                            {
                                // アンプロテクト中
                                // 何か処理

                                // ロック →　再起動
                                mo.InvokeMethod("Enable", null, null);
                                mo.InvokeMethod("RestartSystem", null, null);
                                
                            }

                        }
                    }

```

上記コードでプロテクト中か判断を行い　プロテクト中の動作とアンプロテクト中の動作で処理をわける。

以下に、参考としてコードを記載するが、実行すると 「アクセスが拒否されました」という結果になってしまった。　目的の動作はできた為、ここで一旦止める。

```sample_ng1.cs
// uwfmgr.exe volume protect c: と同じ
            try
            {
                ManagementScope scope = new ManagementScope(@"root\standardcimv2\embedded");

                string driveLetter = "C:";

                // UWF_Volume クラスのインスタンスを作成
                ManagementClass uwfVolumeClass = new ManagementClass(scope, new ManagementPath("UWF_Volume"), null);

                // UWF_Volume インスタンスを取得
                ManagementObjectCollection uwfVolumeCollection = uwfVolumeClass.GetInstances();

                foreach (ManagementObject uwfVolumeInstance in uwfVolumeCollection)
                {
                    using (uwfVolumeInstance)
                    {
                        // ドライブが一致する場合、Protect メソッドを呼び出してプロテクトを行う
                        if (uwfVolumeInstance["DriveLetter"].ToString() == driveLetter)
                        {
                            uwfVolumeInstance.InvokeMethod("Protect", null, null);

                            MessageBox.Show($"ドライブ {driveLetter} が UWF によってプロテクト設定されました。");
                            return;
                        }
                    }

                }

            }
            catch (Exception ex)
            {
                MessageBox.Show($"Exception: {ex.Message} 発生しました");
            }
```

```sample_ng2.cs
// uwfmgr.exe volume unprotect c: と同じ
            try
            {
                ManagementScope scope = new ManagementScope(@"root\standardcimv2\embedded");

                string driveLetter = "C:";

                // UWF_Volume クラスのインスタンスを作成
                ManagementClass uwfVolumeClass = new ManagementClass(scope, new ManagementPath("UWF_Volume"), null);

                // UWF_Volume インスタンスを取得
                ManagementObjectCollection uwfVolumeCollection = uwfVolumeClass.GetInstances();

                foreach (ManagementObject uwfVolumeInstance in uwfVolumeCollection)
                {
                    using (uwfVolumeInstance)
                    {
                        // ドライブが一致する場合、Protect メソッドを呼び出してプロテクトを行う
                        if (uwfVolumeInstance["DriveLetter"].ToString() == driveLetter)
                        {
                            uwfVolumeInstance.InvokeMethod("Unprotect", null, null);

                            MessageBox.Show($"ドライブ {driveLetter} が UWF によってアンプロテクト設定されました。");
                            return;
                        }
                    }

                }

            }
            catch (Exception ex)
            {
                MessageBox.Show($"Exception: {ex.Message} 発生しました");
            }
```