WMI を使用して Windows の更新プログラムのインストール状況を調べる
概要
WMI を使用して現在使用している Windows にインストールされている更新プログラム(KB)をチェックします。
動作環境
動作確認環境
Windows バージョン |
|
.NET Framework バージョン |
|
必須動作環境
Windows バージョン |
|
.NET Framework バージョン |
|
内容
KB とは
KB は「キロバイト」や「キーボード」という表現の略称にも使われるため、一般向けに使用する単語ではないと思いますが、Windows のセキュリティ対応やバグ修正などの更新プログラムのことを ID の頭二文字をとって「KB」と表現する場合があります。
これらの各更新プログラムには ID が割り振られており「KBXXXXXX」というフォーマットで指定されています(XXXXXX は任意の数値。桁数は固定ではない)。ただし、すべての更新プログラムがこのフォーマットにのっとっている訳ではないので注意してください。
ちなみにこの「KB」の本来の名称は「サポート技術情報 (Microsoft Knowledge Base) 」であり、マイクロソフトが Web で公開している技術資料の ID と一致するようになっています。たとえば「KB980218」の更新プログラムであれば、これに対応する技術資料が「http://support.microsoft.com/?kbid=980218」に載っています。
KB のインストール状況を検索するプログラム
サンプルでは Visual Studio 2010 と WPF で説明していますが、KB チェックのプログラムはそれ以前の Visual Studio や Windows Form、コンソールアプリでも使用できます。今回は WMI (Windows Management Instrumentation) を使用して KB のインストール状況を確認します。
- Windows Management Instrumentation (ウィキペディアより)
参照の追加
WMI を使用するために、「ManagementObjectSearcher」クラスや「ManagementObject」クラスを使用しますが、これらのクラスを使用するには「System.Management.dll」を参照する必要があります。
C# のプロジェクトの場合にはソリューション エクスプローラーから「参照設定」を右クリックして「参照の追加」を選択します。
参照の追加ダイアログが表示されたら「.NET」タブから「System.Management」を選択して OK ボタンをクリックします。
ソリューション エクスプローラーの参照設定に「System.Management」が追加されていれば OK です。
VB.NET の場合はプロジェクトのプロパティを開き、左のタブから「参照」をクリック、右にある追加ボタンをクリックします。上記と同じように参照の追加ダイアログが表示されるので「System.Management」を選択して OK ボタンをクリックします。
前の画面に戻り、中央のリストに「System.Management」が追加されていれば OK です。
また、プログラムで名前空間の記述を省略するために下のリストから「System.Management」にチェックを入れましょう。
あと、本来の Tips とは関係ないですが、今回のサンプルでは StringBuilder クラスを使用しているので「System.Text」名前空間にもチェックを入れています。(VB.NET のみ)
画面
今回のサンプルで使用する画面は KB のインストール状況を調べるための実行ボタンと、結果を表示するテキストボックスというシンプルな画面になっています。
WPF で作っていますが Windows Form でも同じような画面は構成可能です。
プログラム
C# では ManagementObjectSearcher
クラスなど名前空間の記述を減らすために、コードの最初に「using System.Management;
」を追加しています。VB.NET ではプロジェクトのプロパティで名前空間をインポートするように指定したので特に記述はいりませんが、インポートしていない場合は「Imports System.Management
」を追記する必要があります。
※C# も VB.NET もクラス名をすべて「System.Management.ManagementObjectSearcher
」のように名前空間から記述する場合は上記の指定はいりません。
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Management; // 追加 (参照から「.NET」より「System.Management」追加)
下記はインストールされている KB の検索とリストアップを行っているコードです。
C#
this.ResultTextBox.Text = "";
// WMI クエリをセットして管理オブジェクト検索クラスを作成
ManagementObjectSearcher query =
new ManagementObjectSearcher("Select * From Win32_QuickFixEngineering");
// WMI クエリを使用して管理オブジェクトコレクションを取得
ManagementObjectCollection queryCollection = query.Get();
StringBuilder builder = new StringBuilder();
// コレクションから管理オブジェクトを列挙する
// ここでは HotFixID を取得
foreach (ManagementObject mo in queryCollection)
{
builder.AppendLine(mo["HotFixID"].ToString());
}
// 取得した KB 一覧をセット
this.ResultTextBox.Text = builder.ToString();
VB.NET
Me.ResultTextBox.Text = ""
' WMI クエリをセットして管理オブジェクト検索クラスを作成
Dim query As ManagementObjectSearcher = _
New ManagementObjectSearcher("Select * From Win32_QuickFixEngineering")
' WMI クエリを使用して管理オブジェクトコレクションを取得
Dim queryCollection As ManagementObjectCollection = query.Get()
Dim builder As System.Text.StringBuilder = New System.Text.StringBuilder()
' コレクションから管理オブジェクトを列挙する
' ここでは HotFixID を取得
For Each mo As ManagementObject In queryCollection
builder.AppendLine(mo("HotFixID").ToString())
Next
' 取得した KB 一覧をセット
Me.ResultTextBox.Text = builder.ToString()
1行目の「ResultTextBox
」は取得結果を表示するためのテキストボックスです。
「new ManagementObjectSearcher
」で管理オブジェクトの検索クラスのインスタンスを作成するとともに、引数に WMI クエリを設定しています。クエリの構文はほぼ SQL 文と等しいので詳しくは SQL 関連で調べてください。「Win32_QuickFixEngineering」は現在のオペレーティング システムに適用される更新を表します。
「query.Get()
」で先ほど指定した WMI クエリで検索を行い、結果を「ManagementObjectCollection
」として返します。
「ManagementObjectCollection
」には更新情報が列挙されているので foreach で「ManagementObject
」を取得し、「HotFixID」パラメータから一意識別子を結果として書き込んでいます。
これを実行すると図のように更新プログラムの ID が一覧として列挙されます。
実行してみるとわかりますが、初回実行時のみやたら処理が遅いです。2回目以降はそれなりに早いです。
System.Management.dll の読み込み、処理が遅いのか WMI クエリの実行が遅いのかははっきりしていませんが、遅いという事実は変わりませんので、もし使用するうえで待ち時間が気になるようであれば、非同期実行にするなどの対応が必要かと思います。