« MT の DB を SQLite へ | メイン | 小手先の最適化は遅くなる? »

2008年01月31日

日常の備忘録:: エラーレポートに WMI から取得した情報を含める

    

今まで、あまり詳しくは知らなかったのだが、WMI を使うとコンピュータの管理情報の多くを取得出来るようだ。
WMI では、MSDN2 の Win32 Classes の左のツリーに並ぶさまざまなクラスの情報を取得できる。
この中で役立ちそうなのはプロセッサーの情報やビデオ、サウンドの情報だろうか。
と言うことで、ビデオの情報を書き出すプログラムを組んでみた。
ソースと実行ファイルはこちら
ダウンロードしなくても見れるようにソースの中身を以下に貼っておく。

#ifndef _WIN32_DCOM
#define _WIN32_DCOM
#endif

#include <windows.h>
#include <wbemidl.h>
#include <oleauto.h>
#include <objbase.h>
#include <comdef.h>
#include <comutil.h>
#include <atlbase.h>
#include <iostream>

#pragma comment(lib, "comsuppw.lib")

void PrintDeviceDescription( IWbemClassObject* pDevice, const wchar_t* type )
{
  HRESULT  hr;
  VARIANT var;
  if( SUCCEEDED(hr = pDevice->Get( _bstr_t(type), 0L, &var, NULL, NULL )) ) {
    VARTYPE vt = V_VT(&var);
    VARIANT *va;
    if( var.vt == (VT_VARIANT|VT_BYREF) ) {
      va = var.pvarVal;
    } else {
      va = &var;
    }

    vt = va->vt; 
    if( (vt&VT_ARRAY) == VT_ARRAY ) {
      SAFEARRAY *psa;
      if( vt & VT_BYREF ) {
        psa = *va->pparray;
      } else {
        psa = va->parray;
      }
      LONG lb, ub;
      SafeArrayGetLBound( psa, 1, &lb );
      SafeArrayGetUBound( psa, 1, &ub );
      ULONG nTargetLen = ub - lb + 1;

      VARIANT *pi;
      hr = SafeArrayAccessData(psa, (void **)&pi);
      for( ULONG i = 0; i < nTargetLen ; i++ ) {
        if( (pi[i].vt != VT_DISPATCH) && (pi[i].vt != VT_VARIANT) && (pi[i].vt != VT_UNKNOWN) && (pi[i].vt != VT_NULL) && (pi[i].vt != VT_EMPTY ) ) {
          std::wcout << type << L" : " << (const wchar_t *)(_bstr_t)_variant_t(var) << std::endl;
        }
      }
      SafeArrayUnaccessData(psa);
    } else if( (vt != VT_DISPATCH) && (vt != VT_VARIANT) && (vt != VT_UNKNOWN) && (vt != VT_NULL) && (vt != VT_EMPTY ) ) {
      std::wcout << type << L" : " << (const wchar_t *)(_bstr_t)_variant_t(*va) << std::endl;
    } else {
      std::wcout << type << L" : unknown" << std::endl;
    }
  }
}
HRESULT PrintVideoController()
{
  HRESULT  hr;
  try {
      if( FAILED(hr = CoInitialize(NULL)) )
      throw _com_error(hr);

    CComPtr<IWbemLocator> pIWbemLocator;
    if( FAILED(hr = pIWbemLocator.CoCreateInstance(__uuidof(WbemLocator), NULL, CLSCTX_INPROC_SERVER ) ) )
      throw _com_error(hr);

    CComPtr<IWbemServices> pIWbemServices;
    if( FAILED(hr = pIWbemLocator->ConnectServer( _bstr_t(L"\\\\.\\root\\cimv2"), NULL, NULL, 0L, 0L, NULL, NULL, &pIWbemServices )) )
      throw _com_error(hr);

    CoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0 );                    

    CComPtr<IEnumWbemClassObject> pEnumDevices;
    if( FAILED(hr = pIWbemServices->CreateInstanceEnum( _bstr_t(L"Win32_VideoController"), 0, NULL, &pEnumDevices ) ) )
      throw _com_error(hr);

      for( ;; ) {
      DWORD  uReturned = 0;
      CComPtr<IWbemClassObject> pDevice;
      if( FAILED(hr = pEnumDevices->Next( 10000, 1, &pDevice, &uReturned ) ) )
        throw _com_error(hr);
      if( uReturned == 0 ) break;

      PrintDeviceDescription( pDevice, L"AcceleratorCapabilities" );
      PrintDeviceDescription( pDevice, L"AdapterCompatibility" );
      PrintDeviceDescription( pDevice, L"AdapterDACType" );
      PrintDeviceDescription( pDevice, L"AdapterRAM" );
      PrintDeviceDescription( pDevice, L"Availability" );
      PrintDeviceDescription( pDevice, L"CapabilityDescriptions" );
      PrintDeviceDescription( pDevice, L"Caption" );
      PrintDeviceDescription( pDevice, L"ColorTableEntries" );
      PrintDeviceDescription( pDevice, L"ConfigManagerErrorCode" );
      PrintDeviceDescription( pDevice, L"ConfigManagerUserConfig" );
      PrintDeviceDescription( pDevice, L"CreationClassName" );
      PrintDeviceDescription( pDevice, L"CurrentBitsPerPixel" );
      PrintDeviceDescription( pDevice, L"CurrentHorizontalResolution" );
      PrintDeviceDescription( pDevice, L"CurrentNumberOfColors" );
      PrintDeviceDescription( pDevice, L"CurrentNumberOfColumns" );
      PrintDeviceDescription( pDevice, L"CurrentNumberOfRows" );
      PrintDeviceDescription( pDevice, L"CurrentRefreshRate" );
      PrintDeviceDescription( pDevice, L"CurrentScanMode" );
      PrintDeviceDescription( pDevice, L"CurrentVerticalResolution" );
      PrintDeviceDescription( pDevice, L"Description" );
      PrintDeviceDescription( pDevice, L"DeviceID" );
      PrintDeviceDescription( pDevice, L"DeviceSpecificPens" );
      PrintDeviceDescription( pDevice, L"DitherType" );
      PrintDeviceDescription( pDevice, L"DriverDate" );
      PrintDeviceDescription( pDevice, L"DriverVersion" );
      PrintDeviceDescription( pDevice, L"ErrorCleared" );
      PrintDeviceDescription( pDevice, L"ErrorDescription" );
      PrintDeviceDescription( pDevice, L"ICMIntent" );
      PrintDeviceDescription( pDevice, L"ICMMethod" );
      PrintDeviceDescription( pDevice, L"InfFilename" );
      PrintDeviceDescription( pDevice, L"InfSection" );
      PrintDeviceDescription( pDevice, L"InstallDate" );
      PrintDeviceDescription( pDevice, L"InstalledDisplayDrivers" );
      PrintDeviceDescription( pDevice, L"LastErrorCode" );
      PrintDeviceDescription( pDevice, L"MaxMemorySupported" );
      PrintDeviceDescription( pDevice, L"MaxNumberControlled" );
      PrintDeviceDescription( pDevice, L"MaxRefreshRate" );
      PrintDeviceDescription( pDevice, L"MinRefreshRate" );
      PrintDeviceDescription( pDevice, L"Monochrome" );
      PrintDeviceDescription( pDevice, L"Name" );
      PrintDeviceDescription( pDevice, L"NumberOfColorPlanes" );
      PrintDeviceDescription( pDevice, L"NumberOfVideoPages" );
      PrintDeviceDescription( pDevice, L"PNPDeviceID" );
      PrintDeviceDescription( pDevice, L"PowerManagementCapabilities" );
      PrintDeviceDescription( pDevice, L"PowerManagementSupported" );
      PrintDeviceDescription( pDevice, L"ProtocolSupported" );
      PrintDeviceDescription( pDevice, L"ReservedSystemPaletteEntries" );
      PrintDeviceDescription( pDevice, L"SpecificationVersion" );
      PrintDeviceDescription( pDevice, L"Status" );
      PrintDeviceDescription( pDevice, L"StatusInfo" );
      PrintDeviceDescription( pDevice, L"SystemCreationClassName" );
      PrintDeviceDescription( pDevice, L"SystemName" );
      PrintDeviceDescription( pDevice, L"SystemPaletteEntries" );
      PrintDeviceDescription( pDevice, L"TimeOfLastReset" );
      PrintDeviceDescription( pDevice, L"VideoArchitecture" );
      PrintDeviceDescription( pDevice, L"VideoMemoryType" );
      PrintDeviceDescription( pDevice, L"VideoMode" );
      PrintDeviceDescription( pDevice, L"VideoModeDescription" );
      PrintDeviceDescription( pDevice, L"VideoProcessor" );
    }
  } catch( _com_error &e ) {
    std::wcout << (const wchar_t *)e.Description() << std::endl;
  }
  CoUninitialize();

    return hr;
}

int _tmain(int argc, _TCHAR* argv[])
{
  PrintVideoController();
  return 0;
}

これでビデオの情報をいろいろと取得できる。
一部、数値のままで意味がわからないものがあるが、それはWin32_VideoController Class を見れば意味がわかる。
後、配列がうまく取れていない。
どうも取得方法が違うようだ。

ただ、難点があって、ドライバが対応していないと情報がない。
ゲームパッドの情報を取ろうとしたら、マニュファクチャー (標準なんとか) とか、標準 HID デバイス とか出て、取得してもどのメーカーの何かさっぱりわからなかったりした。
まあ、MS のパッドや Logitech はちゃんと取得できるので、取得できないメーカーのドライバが手抜きなだけなのだが。



投稿者 Takenori : 2008年01月31日 21:35




comments powered by Disqus
Total : Today : Yesterday : なかのひと