zoukankan      html  css  js  c++  java
  • 从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: clean 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易学易用的特性,又不失强大的功能。
  • 相关阅读:
    linux基础学习2
    linux下部署项目问题
    ThinkPHP上传返回 “文件上传保存错误!”
    jQuery自定义插件
    对于nginx为什么能提高性能
    WebSocket 是什么原理?为什么可以实现持久连接?
    数据库的左右外连接
    漫画说算法--动态规划算法一(绝对通俗易懂,非常棒)
    Integer.MIN_VALUE
    反射
  • 原文地址:https://www.cnblogs.com/4kapple/p/1271359.html
Copyright © 2011-2022 走看看