🛠 入門 WMI: Windows Management Instrumentation

はじめに

WMIとは
Windows オペレーティングシステムの管理情報と操作機能を提供するフレームワーク。簡単に言うと、Windows のシステム情報を取得したり、設定を変更したり、サービスを制御したりするための APIやその枠組みのこと。
WMIの用途
WMI は 「Windowsの管理と監視のための共通API」 として、次のような用途で広く使われている。
- 運用管理(構成収集・監視・一括操作)
- セキュリティ監視
- 自動化スクリプト
システム監視・インベントリ収集
-
PCやサーバの構成情報取得
- OSバージョン、CPU、メモリ、ディスク容量
- ネットワーク構成やMACアドレス
-
資産管理ツール
- SCCM(System Center Configuration Manager)などが内部でWMIを利用
-
監視ツール
- Zabbix、Nagios、PRTG、PrometheusなどでWindows監視時にWMIでCPUやメモリ使用率を取得
障害対応・ログ収集
-
イベントログ収集
- セキュリティログやシステムログの監視
- ブルースクリーンやドライバ問題調査
- WMIでハードウェアステータスやエラーメッセージ取得
リモートからの一括管理操作
- 大量のPCに対する一括操作
- サービスの起動・停止
- プロセスの強制終了
- ファイル配布やスクリプト実行
- PowerShell Remotingによるドメイン全体の制御
セキュリティ監視
-
不審なプロセスやスクリプトの検出
-
WMIイベントサブスクリプションを悪用したマルウェア検出
-
EDR製品
-
WMIでシステム状態をモニタリング
自動化スクリプト
- PowerShellやVBScriptでの運用タスク自動化
- 例:ログインユーザーの一覧取得
- 例:USB接続デバイスの確認
ハードウェア・ドライバ情報取得
- メーカー製管理ツール
- Dell、HP、Lenovoなどの管理ソフトがWMI経由でハードウェア情報を取得
- BIOS情報、温度センサー値
-
Win32_BIOS
,MSAcpi_ThermalZoneTemperature
などのWMIクラスを利用

CIM: Common Information ModelとWMI
CIM: Common Information Modelは業界標準の管理モデルを定義したもので、WMIはそれをWindows上で実装したしくみ。

WMIの基本モデル
WMIは、オブジェクト指向のモデルに基づき、管理対象をクラスとインスタンスで表現する。このモデルは、業界標準であるCIM(Common Information Model)をベースにしており、Windows環境に特化した拡張が加えられている。
WMIの構造は、大きく分けて次の要素で構成される。
- 名前空間(Namespace)
- クラス(Class)
- インスタンス(Instance)
- プロパティとメソッド
- MOF(Managed Object Format)
- プロバイダー(Provider)
- WMIリポジトリ(Repository)
- イベント(Event)
以下、それぞれを詳しく見ていく。
名前空間(Namespace)
名前空間は、WMIクラスを分類するための論理的なコンテナ。最もよく使われるのは root\cimv2
で、OSやハードウェアに関する標準クラスが格納されている。他にも、イベント関連の root\subscription
や、アプリケーション固有の名前空間が存在する。
PowerShellでは、次のようにして名前空間を列挙できる。
Get-WmiObject -Namespace root -Class __Namespace
クラス(Class)
WMIにおけるクラスは、管理対象を表現するための雛形。例えば、Win32_Process
クラスはWindows上のプロセスを、Win32_OperatingSystem
クラスはOS自体を表す。
クラスは、プロパティ(情報を表す属性)とメソッド(操作を提供する関数)を持つ。たとえば、Win32_Process
クラスにはプロセス名を表す Name
プロパティや、プロセスを終了する Terminate()
メソッドがある。
PowerShellでは、クラスのインスタンスだけでなく、クラス定義そのもののメタデータを取得することもできる。これには、[__meta_class]
クエリを使用する。
# クラス定義を取得する例
Get-WmiObject -Query "SELECT * FROM meta_class WHERE __CLASS = 'Win32_Process'"
このクエリを実行すると、クラスのプロパティ、メソッド、修飾子など、定義情報を確認できる。__meta_class
は特別なWMIシステムクラスであり、スキーマ情報にアクセスするために使う。
インスタンス(Instance)
クラスは抽象的な定義だが、実際に動いているプロセスやOS情報は「インスタンス」として表現される。例えば、Win32_Process
クラスに対して、notepad.exe
や explorer.exe
が個別のインスタンスになる。
プロパティとメソッド
インスタンスが持つ情報は「プロパティ」として提供される。Win32_OperatingSystem
なら、OS名やバージョン、メモリ容量といった情報。また、WMIクラスには操作を実行する「メソッド」というものも用意されており、例えば Win32_Service
クラスではサービスの開始や停止を行うメソッドが用意されている。
MOF(Managed Object Format)
WMIクラスは、MOFと呼ばれるテキスト形式のスキーマで定義される。MOFは、名前空間、クラス、プロパティ、メソッドの定義を含むIDL(Interface Definition Language)に似た言語。
例えば、Win32_OperatingSystem
クラスの簡略化したMOFは次のとおり。
[dynamic, provider("WMIProv")]
class Win32_OperatingSystem {
string Caption;
string Version;
datetime InstallDate;
uint64 TotalVisibleMemorySize;
};
この定義はWMIリポジトリに登録され、WMIサービスがアクセスできるようになる。
実体としてのMOFファイルは、Windowsの %SystemRoot%\System32\wbem
ディレクトリに配置されており、*.mof
や *.mfl
ファイルがそれにあたる。これらはシステムクラスやWin32クラスなど、標準で提供されるWMIクラスの定義を含む。管理者や開発者は独自のMOFを定義して登録し、カスタムクラスを追加することもできる。
WMIリポジトリ
WMIリポジトリは、WMIクラス定義や一部のインスタンス情報を格納するデータベース。通常、%SystemRoot%\System32\wbem\Repository
に存在し、WMIサービスによって管理される。
プロバイダー(Provider)
WMIそのものはデータを直接保持しない。実際にデータを取得するのはプロバイダー。プロバイダーは、カーネルAPIやハードウェアドライバ、サービスなどから情報を取得し、WMIクラスを通して公開する。
イベント(Event)
WMIは、単なる情報取得だけでなく、イベント通知機能も提供する。例えば、新しいプロセスが生成されたときや、サービスが停止したときにイベントを発行できる。これにより、監視やトリガー処理が可能になる。
まとめ
WMIは、名前空間とクラスを基盤に、Windowsの管理情報をオブジェクト指向モデルで統一的に扱える仕組み。MOFで定義されたクラスはWMIリポジトリに格納され、プロバイダーを介してリアルタイムな情報にアクセスする。また、イベント通知を利用すれば、状態変化をトリガーにした自動化することもできる。

WMIの名前空間の階層と代表的なクラス
WMIの名前空間の改装および代表的なクラスをまとめると次のようになる。
root -- WMIの最上位名前空間
├─ subscription -- イベント通知やサブスクリプション関連
│
├─ DEFAULT -- 汎用的な管理クラスが含まれる
│
├─ CIMV2 -- Windowsの主要な管理情報(OS、プロセス、ハードウェア)
│ ├─ Win32_OperatingSystem -- OS情報(名前、バージョン)
│ ├─ Win32_Process -- プロセス情報(PID、状態)
│ ├─ Win32_LogicalDisk -- 論理ディスク情報(空き容量、ファイルシステム)
│ ├─ Win32_NetworkAdapter -- ネットワークアダプタ情報(MAC、状態)
│ └─ CIM_ComputerSystem -- コンピュータ情報(メーカー、モデル)
│
├─ SECURITY -- セキュリティ構成情報を管理
│
├─ SecurityCenter2 -- セキュリティ製品(ウイルス対策ソフト)の状態
│ ├─ AntiVirusProduct -- インストールされたウイルス対策ソフト
│ ├─ FirewallProduct -- ファイアウォール情報
│ └─ AntiSpywareProduct -- スパイウェア対策製品情報
│
├─ WMI -- WMIプロバイダーや構成情報
│
├─ Microsoft -- Microsoft製品の管理情報
│ └─ Windows -- Windowsコンポーネントの設定情報
│ ├─ Defender -- Windows Defender関連
│ │ ├─ MSFT_MpPreference -- Defenderの設定
│ │ └─ MSFT_MpThreatDetection -- 脅威検出情報
│ ├─ PowerShellv3 -- PowerShellの実行ポリシーやセッション
│ └─ Update -- Windows Update情報
│
├─ RSOP -- グループポリシー適用結果(Resultant Set of Policy)
│ ├─ Computer -- コンピュータポリシー
│ └─ User -- ユーザポリシー
│
├─ StandardCimv2 -- CIMベースの標準管理情報(PowerShellのCIMコマンドで利用)
│ ├─ MSFT_NetAdapter -- ネットワークアダプタ管理
│ ├─ MSFT_NetIPAddress -- IPアドレス設定
│ ├─ MSFT_Disk -- ディスク管理
│ ├─ MSFT_Volume -- ボリューム管理
│ └─ MSFT_Printer -- プリンタ管理
│
└─ virtualization -- Hyper-V関連
└─ v2 -- Hyper-V仮想化プラットフォームの管理
├─ Msvm_ComputerSystem -- ホストおよびVMの状態
├─ Msvm_VirtualSystemSettingData -- 仮想マシン設定
├─ Msvm_MemorySettingData -- メモリ設定
├─ Msvm_ProcessorSettingData -- CPU設定
└─ Msvm_VirtualEthernetSwitch -- 仮想スイッチ情報

PowerShellでWMIにアクセスしてみよう
TODO

C++でWMIにアクセスしてみよう
基本概念
WMIにアクセスするためのAPIは、COMインターフェースとして提供される。主要なCOMインタフェースとして次のものがある。
- IWbemLocator : WMIサービスに接続する
- IWbemServices : WMIクラス・インスタンスにアクセスする
- IEnumWbemClassObject : クエリ結果を列挙する
- IWbemClassObject : 個々のWMIオブジェクトを表す
また、COMの初期化時には CoInitiaizeEx
によりシングルスレッド COINIT_APARTMENT_THREADED
またはマルチスレッド COINIT_MULTITHREADED
のいずれかを指定し、CoInitializeSecurity
によりセキュリティコンテキストを初期化する必要がある。
手順
以下に典型的な流れを示す。
1. COMライブラリの初期化 (CoInitializeEx)
WMIを使用する前に、COMライブラリを初期化する必要がある。
CoInitializeEx
はスレッド単位でCOMを初期化し、スレッドモデルを指定する。
HRESULT CoInitializeEx(
LPVOID pvReserved, // 予約。必ず NULL を指定
DWORD dwCoInit // スレッドの並列モデルを指定
// COINIT_APARTMENTTHREADED : シングルスレッドアパートメント
// COINIT_MULTITHREADED : マルチスレッドアパートメント
);
例えば、マルチスレッドアパートメントモデルで初期化するには次のように呼び出す。
HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hr)) {
wprintf(L"Failed to initialize COM library. Error code = 0x%X\n", hr);
return 1; // エラー処理
}
2. COMセキュリティの初期化 (CoInitializeSecurity)
WMIの呼び出しには、COMセキュリティの初期化が必要になる。
CoInitializeSecurity
は、プロセス全体のセキュリティ設定を構成する。
HRESULT CoInitializeSecurity(
PSECURITY_DESCRIPTOR pSecDesc, // セキュリティ記述子(通常 NULL)
LONG cAuthSvc, // 認証サービスの数(-1 は既定の設定を使用)
SOLE_AUTHENTICATION_SERVICE *asAuthSvc, // 認証サービス配列(通常 NULL)
void *pReserved1, // 予約。NULL
DWORD dwAuthnLevel, // 認証レベル(例: RPC_C_AUTHN_LEVEL_DEFAULT)
DWORD dwImpLevel, // 偽装レベル(例: RPC_C_IMP_LEVEL_IMPERSONATE)
void *pAuthList, // 認証情報(通常 NULL)
DWORD dwCapabilities, // 追加の機能(例: EOAC_NONE)
void *pReserved3 // 予約。NULL
);
例えば、既定の認証レベルで初期化するには次のように呼び出す。
HRESULT hr = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL
);
if (FAILED(hr)) {
wprintf(L"Failed to initialize security. Error code = 0x%X\n", hr);
CoUninitialize();
return 1;
}
3. IWbemLocator オブジェクトの作成 (CoCreateInstance)
WMIサービスに接続するために、IWbemLocator
のインスタンスを作成する。
HRESULT CoCreateInstance(
REFCLSID rclsid, // 作成するオブジェクトのCLSID
LPUNKNOWN pUnkOuter, // 集約オブジェクト(通常 NULL)
DWORD dwClsContext, // 実行コンテキスト(CLSCTX_INPROC_SERVER など)
REFIID riid, // 要求するインターフェースのIID
LPVOID *ppv // 作成されたオブジェクトを受け取るポインタ
);
例えば、IWbemLocator
を作成するには次のように呼び出す。
IWbemLocator *pLocator = NULL;
HRESULT hr = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(LPVOID *)&pLocator
);
if (FAILED(hr)) {
wprintf(L"Failed to create IWbemLocator object. Error code = 0x%X\n", hr);
CoUninitialize();
return 1;
}
4. WMIサービスに接続する (IWbemLocator::ConnectServer)
IWbemLocator
を使って、指定した名前空間のWMIサービス (IWbemServices
) に接続する。
HRESULT IWbemLocator::ConnectServer(
const BSTR strNetworkResource, // 接続するWMI名前空間(例: L"ROOT\\CIMV2")
const BSTR strUser, // ユーザー名(NULL は現在のユーザー)
const BSTR strPassword, // パスワード(NULL は現在のユーザー)
const BSTR strLocale, // ロケール(通常 NULL)
LONG lSecurityFlags, // セキュリティフラグ(通常 0)
const BSTR strAuthority, // 認証情報(通常 NULL)
IWbemContext *pCtx, // コンテキスト情報(通常 NULL)
IWbemServices **ppNamespace // 接続先の IWbemServices オブジェクト
);
例えば、ローカルの ROOT\CIMV2
に接続するには次のように呼び出す。
IWbemServices *pServices = NULL;
HRESULT hr = pLocator->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"),
NULL,
NULL,
NULL,
0,
NULL,
NULL,
&pServices
);
if (FAILED(hr)) {
wprintf(L"Could not connect to WMI namespace. Error code = 0x%X\n", hr);
pLocator->Release();
CoUninitialize();
return 1;
}
5. セキュリティレベルの設定 (CoSetProxyBlanket)
WMIのインターフェース呼び出しに必要な認証情報を設定する。
HRESULT CoSetProxyBlanket(
IUnknown *pProxy, // 対象のプロキシ(通常 IWbemServices)
DWORD dwAuthnSvc, // 認証サービス(例: RPC_C_AUTHN_WINNT)
DWORD dwAuthzSvc, // 認可サービス(例: RPC_C_AUTHZ_NONE)
OLECHAR *pServerPrincName, // サーバー名(通常 NULL)
DWORD dwAuthnLevel, // 認証レベル(例: RPC_C_AUTHN_LEVEL_CALL)
DWORD dwImpLevel, // 偽装レベル(例: RPC_C_IMP_LEVEL_IMPERSONATE)
RPC_AUTH_IDENTITY_HANDLE pAuthInfo, // 認証情報(NULL は既定)
DWORD dwCapabilities // 追加機能(例: EOAC_NONE)
);
例えば、既定の認証レベルで設定するには次のように呼び出す。
HRESULT hr = CoSetProxyBlanket(
pServices,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE
);
if (FAILED(hr)) {
wprintf(L"Could not set proxy blanket. Error code = 0x%X\n", hr);
pServices->Release();
pLocator->Release();
CoUninitialize();
return 1;
}
6. オブジェクトの操作 (IWbemServices::ExecQuery)
IWbemServices
を使ってWQLクエリを実行し、対象オブジェクトを列挙する。
HRESULT IWbemServices::ExecQuery(
const BSTR strQueryLanguage, // クエリ言語(通常は "WQL")
const BSTR strQuery, // WQLクエリ文字列(例: "SELECT * FROM Win32_Process")
long lFlags, // 実行フラグ(WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY)
IWbemContext *pCtx, // コンテキスト情報(通常 NULL)
IEnumWbemClassObject **ppEnum // 結果を受け取る列挙子ポインタ
);
例えば、オペレーティングシステム情報を取得するには次のように呼び出す。
IEnumWbemClassObject* pEnumerator = NULL;
HRESULT hr = pServices->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_OperatingSystem"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator
);
if (FAILED(hr)) {
wprintf(L"Query for operating system failed. Error code = 0x%X\n", hr);
}
7. 結果の列挙 (IEnumWbemClassObject::Next)
クエリ結果からオブジェクトを1件ずつ取得する。
HRESULT IEnumWbemClassObject::Next(
LONG lTimeout, // タイムアウト(WBEM_INFINITE は無制限)
ULONG uCount, // 取得するオブジェクト数(通常 1)
IWbemClassObject **apObjects, // 取得したオブジェクト配列
ULONG *puReturned // 実際に返された数
);
例えば、Win32_OperatingSystem
の Caption
プロパティを列挙するには次のように呼び出す。
IWbemClassObject *pObj = NULL;
ULONG uReturn = 0;
while (pEnumerator) {
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pObj, &uReturn);
if (0 == uReturn) break;
VARIANT vtProp;
pObj->Get(L"Caption", 0, &vtProp, 0, 0);
wprintf(L"OS Name : %s\n", vtProp.bstrVal);
VariantClear(&vtProp);
pObj->Release();
}
pEnumerator->Release();
8. 後処理 (Release / CoUninitialize)
使用したCOMオブジェクトを解放し、COMライブラリをアンロードする。
// IWbemServices, IWbemLocator などを解放
pServices->Release();
pLocator->Release();
// COMライブラリをアンロード
CoUninitialize();
オブジェクトの操作
WMIでは、IWbemServices
を介してクラスやインスタンスに対して操作を行う。代表的なものは以下の通り。
-
ExecQuery
: クエリで複数インスタンスを取得 -
GetObject
: 単一のクラスまたはインスタンスを取得 -
PutInstance
: インスタンスを更新または作成 -
DeleteInstance
: インスタンスを削除 -
ExecMethod
: メソッドを呼び出す
複数のインスタンスを取得する (ExecQuery)
ExecQuery
は、WQL (WMI Query Language) を使って条件に一致するオブジェクトを列挙する。
HRESULT IWbemServices::ExecQuery(
const BSTR strQueryLanguage, // クエリ言語(通常は "WQL")
const BSTR strQuery, // WQLクエリ文字列(例: "SELECT * FROM Win32_Process")
long lFlags, // 実行フラグ(例: WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY)
IWbemContext *pCtx, // コンテキスト情報(通常 NULL)
IEnumWbemClassObject **ppEnum // 結果を受け取る列挙子ポインタ
);
例えば、現在のオペレーティングシステム情報を取得するには、次のように呼び出す。
IEnumWbemClassObject* pEnumerator = NULL;
HRESULT hr = pServices->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_OperatingSystem"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator
);
if (SUCCEEDED(hr)) {
IWbemClassObject* pObj = NULL;
ULONG uReturn = 0;
while (pEnumerator) {
hr = pEnumerator->Next(WBEM_INFINITE, 1, &pObj, &uReturn);
if (0 == uReturn) break;
VARIANT vtProp;
pObj->Get(L"Caption", 0, &vtProp, 0, 0);
wprintf(L"OS Name : %s\n", vtProp.bstrVal);
VariantClear(&vtProp);
pObj->Release();
}
pEnumerator->Release();
}
単一のインスタンスを取得する (GetObject)
GetObject
は、オブジェクトパスを指定して単一のWMIインスタンスを取得する。
HRESULT IWbemServices::GetObject(
const BSTR strObjectPath, // オブジェクトパス(例: "Win32_Process.Handle='1234'")
long lFlags, // フラグ(通常 0)
IWbemContext *pCtx, // コンテキスト情報(通常 NULL)
IWbemClassObject **ppObject, // 取得したオブジェクトの出力
IWbemCallResult **ppCallResult // 非同期結果(同期なら NULL)
);
例えば、シングルトンである Win32_OperatingSystem
のインスタンスを取得するには
IWbemClassObject* pObj = NULL;
HRESULT hr = pServices->GetObject(
_bstr_t(L"Win32_OperatingSystem=@"), // シングルトンは '@' でアクセス
0,
NULL,
&pObj,
NULL
);
if (SUCCEEDED(hr)) {
VARIANT vtProp;
pObj->Get(L"Caption", 0, &vtProp, 0, 0);
wprintf(L"OS Name: %s\n", vtProp.bstrVal);
VariantClear(&vtProp);
pObj->Release();
}
インスタンスを更新または作成する (PutInstance)
PutInstance
は、既存のインスタンスを更新するか、新しいインスタンスを作成する。
HRESULT IWbemServices::PutInstance(
IWbemClassObject *pInst, // 更新または作成するインスタンス
long lFlags, // 操作フラグ(WBEM_FLAG_UPDATE_ONLY / WBEM_FLAG_CREATE_ONLY / WBEM_FLAG_CREATE_OR_UPDATE)
IWbemContext *pCtx, // コンテキスト情報(通常 NULL)
IWbemCallResult **ppCallResult // 非同期呼び出し時の結果(通常 NULL)
);
例えば、コンピュータ名を変更するには次のように呼び出す。なお、実行には管理者権限が必要になる。
IWbemClassObject* pObj = NULL;
HRESULT hr = pServices->GetObject(
_bstr_t(L"Win32_ComputerSystem.Name='MYPC'"),
0,
NULL,
&pObj,
NULL
);
if (SUCCEEDED(hr)) {
VARIANT vtProp;
VariantInit(&vtProp);
vtProp.vt = VT_BSTR;
vtProp.bstrVal = SysAllocString(L"NEW_NAME");
pObj->Put(L"Name", 0, &vtProp, 0);
VariantClear(&vtProp);
pServices->PutInstance(pObj, WBEM_FLAG_UPDATE_ONLY, NULL, NULL);
pObj->Release();
}
インスタンスを削除する (DeleteInstance)
DeleteInstance
は、オブジェクトパスを指定して該当インスタンスを削除する。
HRESULT IWbemServices::DeleteInstance(
const BSTR strObjectPath, // インスタンスのオブジェクトパス
long lFlags, // フラグ(通常 0)
IWbemContext *pCtx, // コンテキスト情報(通常 NULL)
IWbemCallResult **ppCallResult // 非同期呼び出し時の結果(通常 NULL)
);
例えば、特定のプロセス (PID=1234) を終了するには、次のように呼び出す。
HRESULT hr = pServices->DeleteInstance(
_bstr_t(L"Win32_Process.Handle='1234'"), // PID=1234 のプロセス
0,
NULL,
NULL
);
if (SUCCEEDED(hr)) {
wprintf(L"Process terminated.\n");
}
メソッドを呼び出す (ExecMethod)
ExecMethod
は、クラスやインスタンスに対してメソッドを実行する。
HRESULT IWbemServices::ExecMethod(
const BSTR strObjectPath, // メソッドを呼び出す対象(クラスまたはインスタンスのパス)
const BSTR strMethodName, // メソッド名
long lFlags, // フラグ(通常 0)
IWbemContext *pCtx, // コンテキスト情報(通常 NULL)
IWbemClassObject *pInParams, // 入力パラメータ(NULL可)
IWbemClassObject **ppOutParams, // 出力パラメータ(結果)
IWbemCallResult **ppCallResult // 非同期呼び出し時の結果(通常 NULL)
);
例えば、Win32_Process
クラスの Create
メソッドで notepad.exe
を起動するには、次のように呼び出す。
IWbemClassObject* pClass = NULL;
pServices->GetObject(_bstr_t(L"Win32_Process"), 0, NULL, &pClass, NULL);
IWbemClassObject* pInParamsDefinition = NULL;
pClass->GetMethod(L"Create", 0, &pInParamsDefinition, NULL);
IWbemClassObject* pInParams = NULL;
pInParamsDefinition->SpawnInstance(0, &pInParams);
VARIANT vtProp;
VariantInit(&vtProp);
vtProp.vt = VT_BSTR;
vtProp.bstrVal = SysAllocString(L"notepad.exe");
pInParams->Put(L"CommandLine", 0, &vtProp, 0);
VariantClear(&vtProp);
IWbemClassObject* pOutParams = NULL;
HRESULT hr = pServices->ExecMethod(
_bstr_t(L"Win32_Process"),
_bstr_t(L"Create"),
0,
NULL,
pInParams,
&pOutParams,
NULL
);
if (SUCCEEDED(hr)) {
wprintf(L"Process created successfully.\n");
}
pInParams->Release();
pInParamsDefinition->Release();
pClass->Release();
pOutParams->Release();