2009-09-30 4 views
0

HI 모두 사용하여 내 PC에있는 모든 네트워크 카드의 MAC 주소를 얻을 얻을 수어떻게, WMI

내가 네트워크 어댑터 구성

내가 액세스하려고 MS가 제공하는 코드를 수정하려고

VC++ 2005를 사용하여 Mac 주소 또는 IPAddress 속성 im에 액세스하려고 시도 할 때 null 포인터 예외가 발생합니다. // 여기에서 예외를 확인하십시오. vtProp은 NULL로 반환됩니다. 어디에서 예외가 발생합니까?

#define _WIN32_DCOM 
#include "stdafx.h" 

#include <iostream> 
using namespace std; 
#include <comdef.h> 
#include <Wbemidl.h> 

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

int _tmain(int argc, _TCHAR* argv[]) 
{ 
     HRESULT hres; 

    // Step 1: -------------------------------------------------- 
    // Initialize COM. ------------------------------------------ 

    hres = CoInitializeEx(0, COINIT_MULTITHREADED); 
    if (FAILED(hres)) 
    { 
     cout << "Failed to initialize COM library. Error code = 0x" 
      << hex << hres << endl; 
     return 1;     // Program has failed. 
    } 

    // Step 2: -------------------------------------------------- 
    // Set general COM security levels -------------------------- 
    // Note: If you are using Windows 2000, you need to specify - 
    // the default authentication credentials for a user by using 
    // a SOLE_AUTHENTICATION_LIST structure in the pAuthList ---- 
    // parameter of CoInitializeSecurity ------------------------ 

    hres = CoInitializeSecurity(
     NULL, 
     -1,       // COM authentication 
     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 
     ); 


    if (FAILED(hres)) 
    { 
     cout << "Failed to initialize security. Error code = 0x" 
      << hex << hres << endl; 
     CoUninitialize(); 
     return 1;     // Program has failed. 
    } 

    // Step 3: --------------------------------------------------- 
    // Obtain the initial locator to WMI ------------------------- 

    IWbemLocator *pLoc = NULL; 

    hres = CoCreateInstance(
     CLSID_WbemLocator,    
     0, 
     CLSCTX_INPROC_SERVER, 
     IID_IWbemLocator, (LPVOID *) &pLoc); 

    if (FAILED(hres)) 
    { 
     cout << "Failed to create IWbemLocator object." 
      << " Err code = 0x" 
      << hex << hres << endl; 
     CoUninitialize(); 
     return 1;     // Program has failed. 
    } 

    // Step 4: ----------------------------------------------------- 
    // Connect to WMI through the IWbemLocator::ConnectServer method 

    IWbemServices *pSvc = NULL; 

    // Connect to the root\cimv2 namespace with 
    // the current user and obtain pointer pSvc 
    // to make IWbemServices calls. 
    hres = pLoc->ConnectServer(
     _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace 
     NULL,     // User name. NULL = current user 
     NULL,     // User password. NULL = current 
     0,      // Locale. NULL indicates current 
     NULL,     // Security flags. 
     0,      // Authority (e.g. Kerberos) 
     0,      // Context object 
     &pSvc     // pointer to IWbemServices proxy 
     ); 

    if (FAILED(hres)) 
    { 
     cout << "Could not connect. Error code = 0x" 
      << hex << hres << endl; 
     pLoc->Release();  
     CoUninitialize(); 
     return 1;    // Program has failed. 
    } 

    cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl; 


    // Step 5: -------------------------------------------------- 
    // Set security levels on 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 
    ); 

    if (FAILED(hres)) 
    { 
     cout << "Could not set proxy blanket. Error code = 0x" 
      << hex << hres << endl; 
     pSvc->Release(); 
     pLoc->Release();  
     CoUninitialize(); 
     return 1;    // Program has failed. 
    } 

    // Step 6: -------------------------------------------------- 
    // Use the IWbemServices pointer to make requests of WMI ---- 

    // For example, get the name of the operating system 
    IEnumWbemClassObject* pEnumerator = NULL; 
    hres = pSvc->ExecQuery(
     bstr_t("WQL"), 
     bstr_t("SELECT * FROM Win32_NetworkAdapterConfiguration"), 
     WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
     NULL, 
     &pEnumerator); 

    if (FAILED(hres)) 
    { 
     cout << "Query for NIC(s) name failed." 
      << " Error code = 0x" 
      << hex << hres << endl; 
     pSvc->Release(); 
     pLoc->Release(); 
     CoUninitialize(); 
     return 1;    // Program has failed. 
    } 

    // Step 7: ------------------------------------------------- 
    // Get the data from the query in step 6 ------------------- 

    IWbemClassObject *pclsObj; 
    ULONG uReturn = 0; 

    while (pEnumerator) 
    { 
     HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, 
      &pclsObj, &uReturn); 

     if(0 == uReturn) 
     { 
      break; 
     } 

     VARIANT vtProp; 

     // Get the value of the Name property 

     //hr = pclsObj->Get(L"Caption", 0, &vtProp, 0, 0); 
    //  wcout << " Caption : " << vtProp.bstrVal << endl; 
    //  VariantClear(&vtProp); 
    // pclsObj->Release(); 

     hr = pclsObj->Get(L"MACAddress", 0, &vtProp, 0, 0); 
     // exception here: vtProp is returned as NULL 
     wcout << " MACAddress : " << vtProp.bstrVal << endl; 
     VariantClear(&vtProp); 
     pclsObj->Release(); 


    } 

    // Cleanup 
    // ======== 

    pSvc->Release(); 
    pLoc->Release(); 
    pEnumerator->Release(); 
    // pclsObj->Release(); 
    CoUninitialize(); 

    return 0; // Program successfully completed. 
} 

코드에서 무엇이 잘못 되었습니까 ??

압둘 칼리 크

+0

'hr = pclsObj-> Get (L "MACAddress", 0, & vtProp, 0, 0);'후'hr'의 값은 무엇입니까? –

+0

해당 행을 실행 한 후 hr S_OK 값 –

답변

0

나는 vtProp 변수를 초기화하여 시작할 것 - 그것은 문제가되지해야하지만, 때로는 COM 서버가 밖으로 PARAMS에 대한 가정을;

VariantInit(&vtProp); 

그럼 당신은 반환 된 것 후 vtProp을 검사하고 실제의 형태가 (.vt 회원)이 무엇인지 볼 수 있습니다 - 어쩌면 문자열이 어떤 이유로, 아니다?

형식으로 다시 게시 할 수 있습니까 (oaidl.h의 VARTYPE 정의와 상호 참조하여 친숙한 이름이 무엇인지 알 수 있습니까)?

0

일반적으로 네트워크 어댑터 목록에는 몇 개의 "가상"어댑터가 포함되어 있으며 모두 MAC 주소를 가지고 있지는 않습니다. 일부는 (예 : "패킷 스케줄러 미니 포트") 실제 어댑터의 MAC 주소를 중복합니다. 필드 (VT_EMPTY 일 수 있음)를 확인하고 결과 목록에서 중복을 제거하면됩니다.

2

이것은 오래되었지만 난 아무데도 해결책을 보지 못했다과 같은 문제가. 나는 결과 중 일부는 VT_NULL 왜 이해가 안

if(vtProp.vt != VT_NULL) 
    wcout << " MACAddress : " << vtProp.bstrVal << endl; 

. VT_NULL에 대한 체크를 넣어 그것을 해결하지만 그것이 추가하여 피할 수 의심 "select"문에 "where"절을 사용하십시오.

팁을 주신 피니시 덕분에!