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


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

処理内容

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

参考

情報感謝です。

上記の「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);
    }
}
//---------------------------------------------------------------------------

実行

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

v0.2

情報

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

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);
    }
}
//---------------------------------------------------------------------------

動作

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