使用WMI获得系统信息

学习笔记 -- 使用WMI获得系统信息

WMI是Windows 2K/XP管理系统的核心。WMI以CIMOM为基础,CIMOM即公共信息模型对象管理器(Common Information Model Object Manager),是一个描述操作系统构成单元的对象数据库,为MMC和脚本程序提供了一个访问操作系统构成单元的公共接口。有了WMI,工具软件和脚本程序访问操作系统的不同部分时不需要使用不同的API;相反,操作系统的不同部分都可以插入WMI,工具软件和WMI可以方便地读写WMI。

使用WMI可以干的事情。
使用WMI可以得到操作系统、CPU、内存、主板、磁盘、输入设备、电源等等硬件信息,可得到文件系统、驱动、桌面、共享等等软件信息。并且是通过统一接口来实现。

使用VC6.0编写WMI程序的步骤。
1.初始化COM
使用c++编写WMI程序必须首先初始化COM,因为WMI是以COM为基础的,可使用CoInitializeEx和CoInitializeSecurity来完成初始化。
2.建立一个到WMI名字空间的连接。
使用函数CoCreateInstance和IWbemLocator::ConnectServer完成。
3.设置WMI连接的安全等级。
使用函数CoSetProxyBlanket完成。
4.读去要获得的信息
5.释放应用程序占用的资源
释放COM。

WMI的名字空间和类名。
查看WMI的类名可使用WMI CIM Stdio工具。下载地址:http://download.microsoft.com/download/.NetStandardServer/Install/V1.1/NT5XP/EN-US/WMITools.exe
msdn的详细说明地址:
http://msdn2.microsoft.com/en-us/library/aa394572.aspx

//以下是我近两天写的一个程序,用以获取系统信息。
//通过以下几步使用下面的源代码
//1.复制以下代码做成文件(SystemInfoDlg.h .cpp),加入这两个文件到MFC工程中;
//2.在ResourceView中添加一个新的Dialog,资源ID为IDD_SYSTEMINFO_DIALOG
//3.在Dialog中添加一个TreeCtrl控件,资源ID为IDC_TREE
//4.打开类向导,为IDC_TREE控件添加一个CTreeCtrll类型的控制变量m_tree
//本例中和WMI相关的主要是InitWMI,ClearWMI,ShowOneRoot三个函数。
----------------------------File: SystemInfoDlg.h ------------
// SystemInfoDlg.h : header file
//

#if !defined(AFX_SYSTEMINFODLG_H__6BCA3276_DC40_47CC_ACBF_406E2F136325__INCLUDED_)
#define AFX_SYSTEMINFODLG_H__6BCA3276_DC40_47CC_ACBF_406E2F136325__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <objbase.h>
#include <comdef.h>
#include <Wbemidl.h>
#include <iostream>
#include <string>
#include <atlconv.h>

//#define unsigned short WCHAR TCHAR ;

typedef struct tagTREEITEM{
 unsigned short *strName; //显示名称
 unsigned short *strProperty; //property字符串
 int rvType;
} TREEITEM ;

typedef struct tagTREEROOT{
 TCHAR *strItemName;//tree的显示名称
 unsigned short *strResource;//要访问的资源
 unsigned short *strQuery; //Query语句
 TREEITEM * item ; //item表
} TREEROOT ;

/////////////////////////////////////////////////////////////////////////////
// CSystemInfoDlg dialog

class CSystemInfoDlg : public CDialog
{
// Construction
public:
 CSystemInfoDlg(CWnd* pParent = NULL); // standard constructor

public:
 void ShowAllInfo();
 void ShowOneRoot(HTREEITEM hParent,TREEROOT *treeRoot);

 HTREEITEM m_hTreeRoot;
 TREEROOT * root;

 //WMI
 void InitWMI();
 void ClearWMI();
 CFont m_font;

// Dialog Data
 //{{AFX_DATA(CSystemInfoDlg)
 enum { IDD = IDD_SYSTEMINFO_DIALOG };
 CTreeCtrl m_tree;
 //}}AFX_DATA

 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CSystemInfoDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
 //}}AFX_VIRTUAL

// Implementation
protected:
 HICON m_hIcon;

 // Generated message map functions
 //{{AFX_MSG(CSystemInfoDlg)
 virtual BOOL OnInitDialog();
 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
 afx_msg void OnPaint();
 afx_msg HCURSOR OnQueryDragIcon();
 virtual void OnOK();
 afx_msg void OnDestroy();
 afx_msg void OnTimer(UINT nIDEvent);
 afx_msg void OnSize(UINT nType, int cx, int cy);
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_SYSTEMINFODLG_H__6BCA3276_DC40_47CC_ACBF_406E2F136325__INCLUDED_)

-------------------------------------------------------------------------
----------------------FIle:-----------------------------------
// SystemInfoDlg.cpp : implementation file
//
#include "stdafx.h"
#include "SystemInfo.h"
#include "SystemInfoDlg.h"

#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "ole32.lib")

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
#define TIME_INTERVAL 10
#define MAX_OBJECT 128
#define EXPAND_COUNT 5

//第三项表示获取的值的类型:0--字符串,1-bool,2--整型
TREEITEM itemAntiVirusProduct[]={
 {L"软件名称:",L"DisplayName",0},
 {L"版本:",L"VersionNumber",0},
 {L"生产厂商:",L"CompanyName",0},
 {L"最新病毒库:",L"ProductUptoDate",1},
 {L"pathToUpdateUI",L"pathToUpdateUI",0},
 {NULL,NULL}
};

TREEITEM itemFirewallProduct[]={
 {L"软件名称:",L"displayName",0},
 {L"版本:",L"versionNumber",0},
 {L"生产厂商:",L"CompanyName",0},
 {NULL,NULL,0}
};

TREEITEM itemACE[]={
 {L"GuidObjectType:",L"GuidObjectType",0},
 {L"GuidInheritedObjectType:",L"GuidInheritedObjectType",0},
 {NULL,NULL,0}
};

TREEITEM itemOperatingSystem[]={
 {L"操作系统:",L"Caption",0},
 {L"版本:",L"Version",0},
 {L"BuildType:",L"BuildType",0},
 {L"BuildNumber:",L"BuildNumber",0},
 {L"补丁版本:",L"CSDVersion",0},
 {L"序列号:",L"SerialNumber",0},
 {L"发行商:",L"Manufacturer",0},
 {L"组织名称:",L"Organization",0},
 {L"注册给:",L"RegisteredUser",0},
 {L"网络名:",L"CSName",0},
 {L"系统路径:",L"WindowsDirectory",0},
 {L"System路径:",L"SystemDirectory",0},
 {L"国家代码:",L"CountryCode",0},
 {NULL,NULL,0}
};

TREEITEM itemCIM_OperatingSystem[]={
 {L"总物理内存(KB):",L"TotalVisibleMemorySize",0},
 {L"剩余物理内存(KB):",L"FreePhysicalMemory",0},
 {L"总虚拟内存(KB):",L"TotalVirtualMemorySize",0},
 {L"剩余虚拟内存(KB):",L"FreeVirtualMemory",0},
 {L"空闲内存(KB):",L"FreeSpaceInPagingFiles",0},
 {L"最后一次启动时间:",L"LastBootUpTime",0},
 {NULL,NULL,0}
};

TREEITEM itemWin32_Registry[]={
 {L"最大值:",L"MaximumSize",0},
 {L"当前大小:",L"CurrentSize",0},
 {L"建议大小:",L"ProposedSize",0},
 {NULL,NULL,0}
};

TREEITEM itemCIM_Processor[]={
 {L"设备号:",L"DeviceID",0},
 {L"名称:",L"Description",0},
 {L"最大频率:",L"MaxClockSpeed",0},
 {L"当前频率:",L"CurrentClockSpeed",0},
 {L"地址宽度:",L"AddressWidth",0},
 {L"数据宽度:",L"DataWidth",0},
 {NULL,NULL,0}
};

TREEITEM itemWin32_BIOS[]={
 {L"名称:",L"Description",0},
 {L"SMBIOS版本:",L"SMBIOSBIOSVersion",0},
 {L"语言:",L"CurrentLanguage",0},
 {L"生产厂商:",L"Manufacturer",0},
 {L"序列号:",L"SerialNumber",0},
 {NULL,NULL,0}
};

TREEITEM itemWin32_Service[]={
 {L"名称:",L"DisplayName",0},
 {L"描述:",L"Description",0},
 {L"状态:",L"State",0},
 {L"服务类型:",L"ServiceType",0},
 {L"启动路径:",L"PathName",0},
 {L"启动方式:",L"StartMode",0},
 {NULL,NULL,0}
};

TREEITEM itemWin32_Environment[]={
 {L"名称:",L"Name",0},
 {L"描述:",L"Description",0},
 {L"值:",L"VariableValue",0},
 {NULL,NULL,0}
};

TREEROOT g_treeRoot[] ={
 {"操作系统",L"root\\cimv2",L"Select * from Win32_OperatingSystem",itemOperatingSystem},
 {"CPU",L"root\\cimv2",L"Select * from CIM_Processor",itemCIM_Processor},
 {"内存",L"root\\cimv2",L"Select * from CIM_OperatingSystem",itemCIM_OperatingSystem},
 {"注册表",L"root\\cimv2",L"Select * from Win32_Registry",itemWin32_Registry},
 {"环境变量",L"root\\cimv2",L"Select * from Win32_Environment",itemWin32_Environment},
 {"BIOS",L"root\\cimv2",L"Select * from Win32_BIOS",itemWin32_BIOS},
// {"安全",L"root\\cimv2",L"Select * from Win32_ACE",itemACE},
 {"杀毒软件",L"root\\SecurityCenter",L"Select * from AntiVirusProduct",itemAntiVirusProduct},
 {"防火墙",L"root\\SecurityCenter",L"Select * from FirewallProduct",itemFirewallProduct},
 {"系统服务",L"root\\cimv2",L"Select * from Win32_Service",itemWin32_Service},
 {NULL,NULL,NULL,NULL}
};

class CAboutDlg : public CDialog
{
public:
 CAboutDlg();

// Dialog Data
 //{{AFX_DATA(CAboutDlg)
 enum { IDD = IDD_ABOUTBOX };
 //}}AFX_DATA

 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CAboutDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
 //}}AFX_VIRTUAL

// Implementation
protected:
 //{{AFX_MSG(CAboutDlg)
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
 //{{AFX_DATA_INIT(CAboutDlg)
 //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CAboutDlg)
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
 //{{AFX_MSG_MAP(CAboutDlg)
  // No message handlers
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSystemInfoDlg dialog

CSystemInfoDlg::CSystemInfoDlg(CWnd* pParent /*=NULL*/)
 : CDialog(CSystemInfoDlg::IDD, pParent)
{
 //{{AFX_DATA_INIT(CSystemInfoDlg)
  // NOTE: the ClassWizard will add member initialization here
 //}}AFX_DATA_INIT
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CSystemInfoDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CSystemInfoDlg)
 DDX_Control(pDX, IDC_TREE, m_tree);
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSystemInfoDlg, CDialog)
 //{{AFX_MSG_MAP(CSystemInfoDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_WM_DESTROY()
 ON_WM_TIMER()
 ON_WM_SIZE()
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSystemInfoDlg message handlers

BOOL CSystemInfoDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // Add "About..." menu item to system menu.

 // IDM_ABOUTBOX must be in the system command range.
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }

 SetIcon(m_hIcon, TRUE);   // Set big icon
 SetIcon(m_hIcon, FALSE);  // Set small icon
 
 // TODO: Add extra initialization here
 if(m_font.CreatePointFont(100,"宋体"))
  m_tree.SetFont(&m_font);

 InitWMI();
 m_hTreeRoot = m_tree.InsertItem("本机系统信息",0,0,TVI_ROOT,TVI_LAST);

 ShowAllInfo();
 m_tree.Expand(m_hTreeRoot,TVE_EXPAND); 
 
 return TRUE;  // return TRUE  unless you set the focus to a control
}

void CSystemInfoDlg::ShowAllInfo()
{
 root = g_treeRoot ;
 SetTimer(1,TIME_INTERVAL,NULL);
}

void CSystemInfoDlg::OnTimer(UINT nIDEvent)
{
 if(nIDEvent==1)
 {
  KillTimer(1);
  if(root && root->item)
  {
   ShowOneRoot(m_hTreeRoot,root);
   root ++ ;
   m_tree.Expand(m_hTreeRoot,TVE_EXPAND);  
   SetTimer(1,TIME_INTERVAL,NULL);
  }
  else
  {
   root = NULL ;
   KillTimer(1);
  }
 }

 CDialog::OnTimer(nIDEvent);
}

void CSystemInfoDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CSystemInfoDlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // device context for painting

  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  // Center icon in client rectangle
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  // Draw the icon
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CDialog::OnPaint();
 }
}

HCURSOR CSystemInfoDlg::OnQueryDragIcon()
{
 return (HCURSOR) m_hIcon;
}

void CSystemInfoDlg::OnOK()
{
}

void CSystemInfoDlg::OnDestroy()
{
 ClearWMI();
 CDialog::OnDestroy();
}

void CSystemInfoDlg::InitWMI()
{
 //使用CoInitializeEx和CoInitializeSecurity初始化COM
 HRESULT hres;
 hres = CoInitializeEx(0, COINIT_MULTITHREADED );
 if (FAILED(hres))
 {
  return ; //初始化COM异常:注意,COM只须也只能初始化一次
 }
 hres = CoInitializeSecurity(NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL );
 
 if (FAILED(hres))
 {
  CoUninitialize();
  return ;
 }
}

void CSystemInfoDlg::ClearWMI()
{
    CoUninitialize();
}

void CSystemInfoDlg::ShowOneRoot(HTREEITEM hParent,TREEROOT *treeRoot)
{
 IWbemLocator *pLoc = NULL ;
 IWbemServices *pSvc = NULL ;
 IEnumWbemClassObject *pEnumerator = NULL ;
 IWbemClassObject * m_pWbemClass[MAX_OBJECT] = {NULL};

 _variant_t vProp;
 std::string m_szProduct;
 ULONG uReturn;
 ULONG uCount ;
 CString strItem;
 CString strValue;

 BSTR bszProp = NULL ;
 BSTR m_bszWQL = NULL ;
 BSTR bszQuery = NULL ;

 TREEITEM* currItem=NULL; //循环变量
 HTREEITEM hRoot; //本函数的根Item
 HTREEITEM hCountRoot;//每一次Count循环的Root

 if(!hParent)
  hRoot = m_tree.InsertItem(treeRoot->strItemName,TVI_ROOT,TVI_LAST);
 else
  hRoot = m_tree.InsertItem(treeRoot->strItemName,hParent,TVI_LAST);

 //连接到Server
 HRESULT hres;
 if( FAILED( CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,IID_IWbemLocator,
  (LPVOID *) &pLoc) ))
 {
  goto end;
 }
 
 if( FAILED( pLoc->ConnectServer(_bstr_t(treeRoot->strResource),NULL,NULL,0,NULL,0,0,&pSvc)))
 {
  goto end;
 }

 //设置WMI连接的安全等级。
 if (FAILED(CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL,RPC_C_AUTHN_LEVEL_CALL,
  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE)))
 {
  goto end;
 }

 if(!pSvc) goto end ;

 //列举
 m_bszWQL = SysAllocString ( L"WQL" );
 bszQuery = SysAllocString (treeRoot->strQuery);
 
 if ( m_bszWQL == NULL || bszQuery == NULL)
 {
  goto end ;
 }

 if(FAILED(pSvc->ExecQuery(m_bszWQL,bszQuery,WBEM_FLAG_RETURN_IMMEDIATELY,
  NULL,&pEnumerator)))
 {
  goto end ;
 }

 if(FAILED(pEnumerator->Next( WBEM_INFINITE, MAX_OBJECT, m_pWbemClass, &uReturn ) ))
 {
  goto end ;
 }
 if(uReturn<=0)
 {
  strItem = "未检测到此类型的信息";
  m_tree.InsertItem(strItem,hRoot);
  goto end ;
 }
 for(uCount=0;uCount<uReturn;uCount++)
 {
  //如果有多个结果,新开一级item
  if(uReturn>1)
  {
   hCountRoot = m_tree.InsertItem(treeRoot->strItemName,hRoot,TVI_LAST);
  }
  else
  {
   hCountRoot = hRoot ;
  }

  currItem = treeRoot->item;
  while(currItem->strName!=NULL)
  {
   bszProp = SysAllocString (currItem->strProperty);
   hres = m_pWbemClass[uCount]->Get ( bszProp, 0, &vProp, 0, 0 );
   if ( FAILED ( hres ) )
   {
    SysFreeString ( bszProp );
    currItem++ ;
    continue;
   }
  
   //显示
   strItem = currItem->strName;
   if( (vProp.vt == VT_EMPTY) || (vProp.vt == VT_NULL) )
   {
    SysFreeString ( bszProp );
    currItem++ ;
    continue ;
   }

   if(currItem->rvType ==0 ) //字符串
   {
    m_szProduct = (_bstr_t)vProp ;   
    strValue = m_szProduct.c_str();
   }
   else if(currItem->rvType==1) //bool
   {
    if(vProp.boolVal)
    {
     strValue = "是";
    }
    else
    {
     strValue = "否";
    }
   }
   else if(currItem->rvType==2)
   {
    strValue.Format("%d",vProp.intVal);
   }  
  
   if(uReturn>1 && currItem == treeRoot->item)
   { //如果有多个结果,则在第一子项时修改新一级item的名称
    m_tree.SetItemText(hCountRoot,strValue);
   }

   strItem += strValue;
   m_tree.InsertItem(strItem,hCountRoot);
   SysFreeString ( bszProp );
   currItem++ ;
  }
 }

 if(uReturn<EXPAND_COUNT) //当项目不多时,展开
  m_tree.Expand(hRoot,TVE_EXPAND);

end:
 if(bszProp) SysFreeString ( bszProp );
 if(m_bszWQL) SysFreeString ( m_bszWQL );
 if(bszQuery) SysFreeString ( bszQuery );

 if(pEnumerator) pEnumerator->Release();
 for(int i=0;i<MAX_OBJECT;i++) if(m_pWbemClass[i]) m_pWbemClass[i]->Release();
 if(pSvc) pSvc->Release();
    if(pLoc) pLoc->Release(); 
}

void CSystemInfoDlg::OnSize(UINT nType, int cx, int cy)
{
 CDialog::OnSize(nType, cx, cy);

 CRect rc;
 GetClientRect(rc);
 if(IsWindowVisible())
  m_tree.MoveWindow(rc);
}


 

你可能感兴趣的:(职场,休闲,wmi, ,使用WMI获得系统信息)