'COM'에 해당되는 글 1건
- 2008.12.01 WMI를 이용하여 PC 제조번호 가져오기 2
WMI는 은근히 재미있는 주제입니다. COM을 사용하는 방법과 WMI에 접근하는 방법을 같이 공부할 수 있거든요.
또한, AD를 사용한다면, 에이전트 없이 원격 클라이언트의 정보를 상당량 수집할 수 있구요.
WMI에 대한 자세한 설명은 MSDN을 참조해주시구요, 전체적인 과정을 살펴보면 대략 다음과 같습니다.
1. CoInitialize로 COM을 초기화한다.
2. CoInitializeSecurity로 보안 레벨을 설정한다.
3. CoCreateInstance로 WMI 의 COM Object 를 생성한다.
4. ConnectServer로 "root\\cimv2" 네임스페이스로 접속한다.
5. ExecQuery 로 WQL 구문을 실행한다.
6. 실행결과 Enumerator 를 분석하고, 제조번호를 파싱한다.
그리하여, 전체 코드는 다음과 같이 되겠습니다.
#include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { int nRet = 0; HRESULT hr = S_OK; TCHAR tszMsg[1024] = {0, }; try { if (_tsetlocale(LC_ALL, _T("")) == NULL) throw _T("_tsetlocale"); hr = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hr)) throw _T("CoInitialize"); hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); if (FAILED(hr)) throw _T("CoInitializeSecurity"); CComPtr<IWbemLocator> wbemLocater = NULL; hr = CoCreateInstance( CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&wbemLocater); if (FAILED(hr)) throw _T("CoCreateInstance"); CComPtr<IWbemServices> wbemServices = NULL; hr = wbemLocater->ConnectServer(L"root\\cimv2", NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &wbemServices); if (FAILED(hr)) throw _T("ConnectServer"); CComPtr<IEnumWbemClassObject> wbemEnumerator = NULL; hr = wbemServices->ExecQuery(L"WQL", L"SELECT * FROM Win32_ComputerSystemProduct", WBEM_FLAG_FORWARD_ONLY, NULL, &wbemEnumerator); if (FAILED(hr)) throw _T("ExecQuery"); ULONG uReturned; while (wbemEnumerator) { CComPtr<IWbemClassObject> wbemObject = NULL; hr = wbemEnumerator->Next( WBEM_INFINITE, 1, &wbemObject, &uReturned); if (FAILED(hr)) throw _T("Next"); if (uReturned == 0) break; _variant_t vtProp; hr = wbemObject->Get(L"IdentifyingNumber", 0, &vtProp, 0 ,0); if (FAILED(hr)) throw _T("Get"); wprintf(_T("%s\n"), (LPCTSTR)vtProp.bstrVal); } } catch (LPTSTR tszErr) { DWORD dwErr = GetLastError(); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, hr, 0, tszMsg, sizeof(tszMsg), NULL); if (*tszMsg == 0) { BSTR bstrErr; IErrorInfo* pErrInfo; GetErrorInfo(0, &pErrInfo); pErrInfo->GetDescription(&bstrErr); if (*bstrErr == 0) { if (*tszMsg == 0) { FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, dwErr, 0, tszMsg, sizeof(tszMsg), NULL); } } } _tprintf(_T("Error: [%s] %s\n"), tszErr, tszMsg); nRet = 1; } catch (...) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, tszMsg, sizeof(tszMsg), NULL); _tprintf(_T("Error: [UnExpected], %s\n"), tszMsg); nRet = 1; } CoUninitialize(); return nRet; }