学习笔记 -- 使用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);
}