概要
Windows10Iotの機能 統合環境フィルターでプロテクトをかけたPCについて、ブチギリを繰り返すと、オシロスコープ接続用のマネージャー(他社製)が立ち上がらなくなる現象が、発生した。
原因がわからないが、プロテクト解除 → 再起動 → マネージャー起動 という形で治るのでアプリケーション(C#)にて現象を捉えたら 統合環境フィルターの設定を操作する事とした。
管理者権限アプリケーションの作成
マニフェストの作成
統合環境フィルターを操作する為には、管理者権限を持ったアプリケーションを作成する必要がある。
プロジェクトを作成後→「追加」→「新しい項目」→「アプリケーションマニフェスト ファイル」 を作成する
下記の様にファイルを変更する。
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
asInvoker アプリケーションは、それを開始したプロセスと同じアクセス許可レベルで実行
requireAdministrator アプリケーションは、管理者のアクセス許可を使用して実行
ユーザーアカウント制御(UAC)
ユーザーアカウント制御を無効としないと、起動の度に確認画面が出力される為、無効とする
Windows10の場合、「コントロールパネル」→「ユーザーアカウント」→「ユーザーアカウント制御設定の変更」→「コンピュータに対する変更の通知タイミング」設定を「通知しない」
WMI (Windows Management Instrumentation)の参照
統合環境フィルターの制御をWMIを介して実施する。
プロジェクトの参照に「System.Management」を追加する
「追加」→「参照」→「System.Management」
実装したコードが以下となる
コード
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);
}
}
}
上記コードでプロテクト中か判断を行い プロテクト中の動作とアンプロテクト中の動作で処理をわける。
以下に、参考としてコードを記載するが、実行すると 「アクセスが拒否されました」という結果になってしまった。 目的の動作はできた為、ここで一旦止める。
// 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} 発生しました");
}
// 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} 発生しました");
}