WMI | C++ Builder > Variant型使用 > 無効なエラーです > 対処

```txt:動作環境
C++ Builder XE4
Windows 7 Pro (32bit)
```

### 処理内容

- Variant型を使いWMIでProcessorの情報を読取る

### 参考

- [C++BuilderからWMIを呼び出す](http://www.acot.net/WMI/index.html) @ 株式会社エイコット 様

情報感謝です。

上記の「2. Variantを使う」を元にXE4向けの実装に変更しました。

## v0.1
### 実装

```Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TButton *Button1;
	TMemo *Memo1;
	void __fastcall Button1Click(TObject *Sender);
private:	// ユーザー宣言
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
```

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	Memo1->Lines->Clear();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	// Variant を使う
	Variant vX, vY, vZ, vi;

	vX = Variant::CreateObject(L"WbemScripting.SWbemLocator");
	vY = vX.OleFunction(L"ConnectServer");
	vZ = vY.OleFunction(L"ExecQuery", L"SELECT * FROM Win32_DiskDrive");
	int cnt = vZ.OlePropertyGet(L"Count"); // (1) 無効なクエリー

	String wrk;
	for (int idx = 0; idx < cnt; idx++) {
		vi = vZ.OleFunction<int>(L"ItemIndex", idx);
		wrk = vi.OlePropertyGet(L"Caption");
		Memo1->Lines->Add(wrk);
	}
}
//---------------------------------------------------------------------------
```

### 実行

ボタン押下時に下記となる。

![2018-11-13_19h07_09.png](https://qiita-image-store.s3.amazonaws.com/0/32870/9b80f993-e650-0eb9-cdae-21d14270b7f6.png)

## v0.2

### 情報

自分が過去にStackOverflowで質問していた質問。
質問の半年後にVariantを使った回答例が付いていた。

- [C++ Builder WMI : Invalid Query](https://stackoverflow.com/questions/20062151/c-builder-wmi-invalid-query)


`vZ = vY.OleFunction(L"ExecQuery", L"SELECT * FROM Win32_DiskDrive");`
を
`vZ = vY.OleFunction("ExecQuery", OleVariant("SELECT * FROM Win32_Processor"));`
に変更すればいいとのこと (by Richard Thomas Edwards)。

### 実装

```Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TButton *Button1;
	TMemo *Memo1;
	void __fastcall Button1Click(TObject *Sender);
private:	// ユーザー宣言
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
```

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	Memo1->Lines->Clear();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	// Variant を使う
	Variant vX, vY, vZ, vi;

	vX = Variant::CreateObject(L"WbemScripting.SWbemLocator");
	vY = vX.OleFunction(L"ConnectServer");
	//vZ = vY.OleFunction(L"ExecQuery", L"SELECT * FROM Win32_DiskDrive");
	vZ = vY.OleFunction("ExecQuery", OleVariant("SELECT * FROM Win32_Processor"));
	int cnt = vZ.OlePropertyGet(L"Count"); // (1) 無効なクエリー が出たところ

	String wrk;
	for (int idx = 0; idx < cnt; idx++) {
		vi = vZ.OleFunction<int>(L"ItemIndex", idx);
		wrk = vi.OlePropertyGet(L"Caption");
		Memo1->Lines->Add(wrk);
	}
}
//---------------------------------------------------------------------------
```

### 動作

エラーは出なくなりました。

![2018-11-13_19h15_16.png](https://qiita-image-store.s3.amazonaws.com/0/32870/53040f33-3c23-efb0-9218-67e00d22c798.png)