C#でWMIを利用して、OSのログオフ(サインアウト)、シャットダウン、再起動をする方法を紹介します。
WMIとはWindows Management Infrastructureの略で、Windowsにおいて、システムについての様々な情報をソフトウェアなどから統一的な方法で取得・設定できるようにする、Windowsのシステム管理を行うためのインターフェイスです。
WMIを利用することで、Windowsのシステム情報が取得できる他、日付の設定やシャットダウンなどの操作を行うことができます。
WMIを利用してOSをシャットダウンする
WMIを操作するには、System.Management名前空間にあるManagementClassクラスを使用します。
ManagementClassクラスを使用することで、ディスクドライブを表す「Win32_LogicalDisk」や、Notepad.exeなどのプロセスを表す「Win32_Process」などの WMIクラスを作成できます。
Windowsのシャットダウン処理では、「Win32_OperatingSystem」クラスを作成して利用します。
ManagementClassクラスを使用してWin32_OperatingSystemクラスを作成するには、ManagementClassクラスのパラメーター(コンストラクタの引数)に文字列 “Win32_OperatingSystem” を渡してインスタンスを生成します。
1 2 |
// ManagementClassのインスタンスを生成 ManagementClass managementClass = new ManagementClass("Win32_OperatingSystem") |
生成したManagementClassオブジェクトのGetメソッドを使用して、Win32_OperatingSystemオブジェクトを取得して使用できるようにします。
1 2 |
// Win32_OperatingSystemオブジェクトを取得する managementClass.Get(); |
ManagementClassオブジェクトのScopeプロパティで取得できる、ManagementScopeオブジェクトのOptionsプロパティで取得できる、ConnectionOptionsオブジェクトのEnablePrivilegesプロパティにTrueを指定して、適切な権限を利用可能にします。
1 2 |
// 特権を有効にする managementClass.Scope.Options.EnablePrivileges = true; |
ManagementClassオブジェクトのGetInstancesメソッドで、WMIのインスタンス(オブジェクト)のコレクションを取得します。
1 2 |
// ManagementObjectCollection managementObjectCollection = managementClass.GetInstances(); |
コレクションを列挙してManagementObjectを取得します。
1 2 3 4 5 |
// WMIのオブジェクトを列挙する foreach (ManagementObject managementObject in managementObjectCollection) { // ... } |
ManagementObjectのInvokeMethodメソッドでシャットダウン処理を実行します。
InvokeMethodメソッドのパラメーターには、実行するメソッド名(文字列)とメソッドのパラメーター(オブジェクト配列)を指定します。
1 2 |
// シャットダウン処理を実行 managementObject.InvokeMethod("Win32Shutdown", new object[] { 1, 0 }); |
メソッドの実行後、ManagementObjectのDisposeメソッドでリソースを開放します。
1 2 |
// リソースを開放 managementObject.Dispose(); |
サンプルプログラム
サンプルプログラムとして、Windowsのシャットダウンオプションを実行できるデスクトップアプリケーションを作成します。
サンプルプログラムを実装するためには、Visual Studioで作成したC#のプロジェクトにアセンブリ(System.Management.dll)への参照を追加する必要があります。
アセンブリを追加する方法については、以下の記事を参考にしてください。
ユーザーインターフェース
サンプルプログラムはWindowsフォームアプリケーションで作成します。
フォームを作成し、シャットダウン処理を行うためのログオフ(サインアウト)ボタン(button1)、シャットダウンボタン(button2)、再起動ボタン(button3)、電源オフボタン(button4)を配置します。また、シャットダウン処理を強制的に実行するかどうかを示すチェックボックスも配置します。
サンプルコード
ログオフ(サインアウト)、シャットダウン、再起動、電源オフの各ボタンのクリック時のイベント処理を実装します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
using System; using System.Windows.Forms; // System.Management.dllの参照が必要 using System.Management; using System.Threading; namespace WindowsFormsApp1 { public partial class Form1 : Form { // コンストラクタ public Form1() { InitializeComponent(); } // シャットダウン private static void Win32Shutdown(int shutdownFlags) { Thread thread = new Thread(() => { // Win32_OperatingSystemクラスを作成する using (ManagementClass managementClass = new ManagementClass("Win32_OperatingSystem")) { // Win32_OperatingSystemオブジェクトを取得する managementClass.Get(); // 権限を有効化する managementClass.Scope.Options.EnablePrivileges = true; // WMIのオブジェクトのコレクションを取得する ManagementObjectCollection managementObjectCollection = managementClass.GetInstances(); // WMIのオブジェクトを列挙する foreach (ManagementObject managementObject in managementObjectCollection) { // InvokeMethodでWMIのメソッドを実行する managementObject.InvokeMethod( // 実行メソッド名 "Win32Shutdown", // メソッドの引数をオブジェクト配列で指定 new object[] { shutdownFlags, 0 } ); // WMIのオブジェクトのリソースを開放 managementObject.Dispose(); } } }); // スレッドモデルをSTAに設定する thread.SetApartmentState(ApartmentState.STA); // スレッドを実行する thread.Start(); // スレッドの終了を待つ thread.Join(); } // シャットダウン実行 private void RunWin32Shutdown(Win32ShutdownFlags shutdownFlags) { int flags = (int)shutdownFlags; if (checkBox1.Checked) { // 強制的に実行 flags += (int)Win32ShutdownFlags.Forced; } Win32Shutdown(flags); } // ログオフ(サインアウト) private void button1_Click(object sender, EventArgs e) { RunWin32Shutdown(Win32ShutdownFlags.Logoff); } // シャットダウン private void button2_Click(object sender, EventArgs e) { RunWin32Shutdown(Win32ShutdownFlags.Shutdown); } // 再起動 private void button3_Click(object sender, EventArgs e) { RunWin32Shutdown(Win32ShutdownFlags.Reboot); } // 電源オフ private void button4_Click(object sender, EventArgs e) { RunWin32Shutdown(Win32ShutdownFlags.PowerOff); } } // シャットダウンフラグ enum Win32ShutdownFlags { // ログオフ(サインアウト) Logoff = 0, // シャットダウン Shutdown = 1, // 再起動 Reboot = 2, // 電源オフ PowerOff = 8, // 強制的に実行 Forced = 4 } } |
プログラムの実行
プロジェクトをビルドして実行(デバッグ)します。
上記の画面が表示され、各ボタンをクリックした際に、シャットダウン処理が実行されれば実装は完了です。