从WMI看VC++到.Net的变迁

WMI(Windows Management Instrumentation)是Windows下可以与系统信息(包括软硬件等)的一个管理框架,通过WMI可以很方便地对机器进行管理。现在以通过WMI来打开(或创建)一个记事本(notepad.exe)进程为例,看看VC++到.Net的变迁,一览.Net是如何让程序员从繁琐晦涩的程序中解放出来。

1、预工作:
VC++中需要在源代码中加入:
#include <Wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")

VC#中需要:
在工程中添加引用:System.Management
在代码中加入using System.Management;

2、流程:
VC++的代码,需要6步和查询返回值、最后释放资源:
//  Step 1: --------------------------------------------------
//  Initialize COM. ------------------------------------------
hres  =   CoInitializeEx( 0 , COINIT_MULTITHREADED); 

//  Step 2: --------------------------------------------------
//  Set general COM security levels --------------------------
hres  =   CoInitializeSecurity(
        NULL, 
        
- 1 ,                           //  COM negotiates service
        NULL,                         //  Authentication services
        NULL,                         //  Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,    //  Default authentication 
        RPC_C_IMP_LEVEL_IMPERSONATE,  //  Default Impersonation  
        NULL,                         //  Authentication info
        EOAC_NONE,                    //  Additional capabilities 
        NULL                          //  Reserved
        );

//  Step 3: ---------------------------------------------------
//  Obtain the initial locator to WMI -------------------------
IWbemLocator  * pLoc  =  NULL;
hres 
=  CoCreateInstance(
        CLSID_WbemLocator,             
        
0
        CLSCTX_INPROC_SERVER, 
        IID_IWbemLocator, (LPVOID 
* & pLoc);

//  Step 4: ---------------------------------------------------
//  Connect to WMI through the IWbemLocator::ConnectServer method
IWbemServices  * pSvc  =  NULL;
//  Connect to the local root\cimv2 namespace
//  and obtain pointer pSvc to make IWbemServices calls.
hres  =  pLoc -> ConnectServer(
        _bstr_t(L
" ROOT\\CIMV2 " ), 
        NULL,
        NULL, 
        
0
        NULL, 
        
0
        
0
        
& pSvc
    );

//  Step 5: --------------------------------------------------
//  Set security levels for the proxy ------------------------
hres  =  CoSetProxyBlanket(
        pSvc,                        
//  Indicates the proxy to set
        RPC_C_AUTHN_WINNT,            //  RPC_C_AUTHN_xxx 
        RPC_C_AUTHZ_NONE,             //  RPC_C_AUTHZ_xxx 
        NULL,                         //  Server principal name 
        RPC_C_AUTHN_LEVEL_CALL,       //  RPC_C_AUTHN_LEVEL_xxx 
        RPC_C_IMP_LEVEL_IMPERSONATE,  //  RPC_C_IMP_LEVEL_xxx
        NULL,                         //  client identity
        EOAC_NONE                     //  proxy capabilities 
    );

//  Step 6: --------------------------------------------------
//  Use the IWbemServices pointer to make requests of WMI ----
//  set up to call the Win32_Process::Create method
BSTR MethodName  =  SysAllocString(L " Create " );
BSTR ClassName 
=  SysAllocString(L " Win32_Process " );

IWbemClassObject
*  pClass  =  NULL;
hres 
=  pSvc -> GetObject(ClassName,  0 , NULL,  & pClass, NULL);

IWbemClassObject
*  pInParamsDefinition  =  NULL;
hres 
=  pClass -> GetMethod(MethodName,  0
        
& pInParamsDefinition, NULL);

IWbemClassObject
*  pClassInstance  =  NULL;
hres 
=  pInParamsDefinition -> SpawnInstance( 0 & pClassInstance);

//  Create the values for the in parameters
VARIANT varCommand;
varCommand.vt 
=  VT_BSTR;
varCommand.bstrVal 
=  L " notepad.exe " ;
//  Store the value for the in parameters
hres  =  pClassInstance -> Put(L " CommandLine " 0 ,
        
& varCommand,  0 );
wprintf(L
" The command is: %s\n " , V_BSTR( & varCommand));

//  Execute Method
IWbemClassObject *  pOutParams  =  NULL;
hres 
=  pSvc -> ExecMethod(ClassName, MethodName,  0 , NULL, pClassInstance,  & pOutParams, NULL);

//  Get return value
VARIANT varReturnValue;
hres 
=  pOutParams -> Get(_bstr_t(L " ReturnValue " ),  0 & varReturnValue, NULL,  0 );

//  Last: c lean up
VariantClear( & varCommand);
VariantClear(
& varReturnValue);
SysFreeString(ClassName);
SysFreeString(MethodName);
pClass
-> Release();
pInParamsDefinition
-> Release();
pOutParams
-> Release();
pLoc
-> Release();
pSvc
-> Release();
CoUninitialize();

VC#只需寥寥数行就可以实现(暂不考虑错误处理):
跳过VC++中的Step1~5,直接从Step6开始。而且非常直观:
ManagementClass mc  =   new   ManagementClass( " Win32_Process " );
ManagementBaseObject obj 
=  mc.GetMethodParameters( " Create " );
obj[
" CommandLine " ] = " notepad.exe " ;
mc.InvokeMethod(
" Create " , obj,  null );
mc.Dispose();

.Net对WMI良好的封装,还有对字符串的更强支持、方便的垃圾回收机制,使程序既一目了然,又易于维护。其实类似的区别在VC vs VB年代已经出现了(特别是在COM组件编写和调用方面可以看出),从这点也可以看出.Net完全继承了VB易学易用的特性,又不失强大的功能。

你可能感兴趣的:(.net)