[C++]WMI 질의 만들기 - 1

2023. 2. 12. 19:20프로그래밍

728x90

 

 

Making WMI Queries In C++

An example-driven guide on how to write WMI consumers in C++.

www.codeproject.com

 

C++ 예제 중심의 WMI 소비자(consumer) 작성 방법에 대한 가이드입니다.

요약

WMI 소비자 프로그래밍에 대한 문서를 인터넷에서 검색 해 보면, 대부분의 검색 문서가 C# 프로그래머용으로 작성되어 있었습니다.

C++에서 WMI를 사용하는 방법에 대한 문서는 매우 드뭅니다. MSDN에서 많은 C++ 코드 조각을 제공 하고 있는데도 엄청 더 놀라운 일인 겁니다.그러나 이러한 코드 조각으로는 실제 자습서를 만들어 내지 못하죠. 이 문서에서는 WMI 소비자를 구현하는 방법의 다양한 면들을 다루게 됩니다.

과정과 함께 제공되는 예제는 쿼리를 통한 WMI 정보를 검색하는 방법에 대해서 관심을 가집니다.

입문적인 성격이기는 하지만, 이 기사는 독자가 C++ 컨텍스트에서 (D)COM 프로그래밍에 익숙하다고 가정합니다. SQL에 대한 어느 정도의 지식은 장점이지만 필수 사항은 아닙니다.

 

I. 소개

동기

일반 사용자가 반드시 그렇게 인식하는 것은 아니지만 운영 체제는 컴퓨터 하드웨어만큼이나 놀라운 진화를 거듭하고 있습니다.

공룡이 지구를 지배 했던 석기 시대에 컴퓨터는 특정 작업을 수행하도록 설계 된 전선과 진공관으로 가득 찬 괴물 같은 검은 상자이며 전선으로 연결 되어 있었습니다.

이것이 현대 운영 체제의 초창기 조상이었습니다. 특히 관리자에 대한 지원을 전혀 하지 않았습니다.

이것은 부분적으로 그 당시에 5대의 컴퓨터에 설치된 사용자 기반이기때문에, 그런 지원들이 필요하지 않았기 때문입니다.오늘날 이 진화의 최초의 종점에서 되돌아 보면 모든 것이 크게 바뀌었습니다.

최신 컴퓨터는 유례없는 다재다능함을 지닌 모든 곳에 존재하는 만능인 도구가 되었습니다.

그들의 운영 체제는 점점 더 커지고 더욱 정교한 환경이 되었습니다. 가장 중요한 것은 이전의 "특수 아키텍처" 기계가 아니라는 것입니다. 각 컴퓨터는 엄청난 수의 하드웨어 및 소프트웨어 구성을 지원할 수 있습니다.

운영 체제는 변화를 반영하고 있습니다. 예를 들어 Windows 95부터 Microsoft는 환경 구성 데이터를 저장하기위해서 중앙 집중식 장소로 레지스트리를 도입했습니다.

시스템 관리를 위한 기타 도구 및 구성 요소들이 추가되었습니다.

오늘날 네트워킹 기능은 핵심 요구 사항이기 때문에 당신이 가진 데스크탑의 로컬 컴퓨터 워크스테이션뿐만 아니라 네트워킹 인프라도 관리하기 위한 통합 운영 체제 지원이 점점 더 중요해지고 있습니다.

100대 이상의 컴퓨터로 쉽게 구성된 회사 네트워크에서는 원격 관리 기능이 특히 이득이 됩니다.

WMI(Windows Management Instrumentation)는 이러한 요구에 대한 통합 솔루션입니다.

WMI 응용 프로그램의 두드러진 예 하나가 Windows XP 및 Windows 2000에 내장 작업 모니터입니다. 이것은 WMI의 중요한 기능을 - 자체 응용 프로그램에서 호출할 수 있는 WMI용 API를 가지고 있습니다 - 인상적으로 보여줍니다.

이것은 유틸리티 응용 프로그램을 호출하는 것보다 다소 번거로운 방법을 의미 하는 것이며, 명령줄 인터프리터를 통한 PING.EXE 및 결과에 대한 출력 구문 분석은 더 이상 필요하지 않습니다.

프로그래머의 관점에서 볼 때 WMI는 많은 시스템 관리 관련 데이터 구조에 대한 동기 및 비동기 액세스의 다양한 방법을 제공하는 DCOM 기반 서비스입니다.

이 정보의 대부분은 다른 방법으로 액세스할 수 있지만 WMI를 프로그래머에게 상당히 호의적으로 보이게 만들 수 있는 통합 API입니다.

이 나머지 섹션에서는 일반적인 SQL 파생물인 WQL 및 WMI에 대한 간략한 개요를 제공 할 것입니다.두 번째 섹션에서는 로컬 컴퓨터의 동기 쿼리를 다룹니다.

비동기 쿼리는 섹션 3의 주제입니다. 마지막으로 네 번째 섹션에서는 WMI와의 세 번째 형태의 통신인 이벤트에 대해 설명합니다.

 

WMI 및 WQL 개요

Windows Management Instrumentation 혹은 WMI는 모든 기업이 포함되어 있는 네트워크에서 컴퓨터에 대한 상태 또는 성능 데이터를 응용 프로그램에 제공합니다.

Win32(resp. Win64) 시스템, 레지스트리 또는 기타 사용자 지정 소스와 같은 다양한 소스에서 이 데이터를 가져 옵니다.

특히 전체 상태 또는 성능 데이터를 보다 추상적인 보기로 제공하기 위해서 데이터의 실제 위치는 WMI-API에 의해 숨겨집니다.

WMI는 관리 객체(managed object)라는 개념을 도입했습니다. 관리 객체(managed object)는 WMI에서 관리하는 컴퓨터의 일부 논리적 또는 물리적 구성 요소입니다.

예를 들어 하드 디스크 드라이브의 파티션은 관리 객체(managed object)입니다. 또 다른 예는 SNMP 서비스 또는 프로세서와 같은 물리적 구성 요소 일 것입니다.

더 높은 수준에서 예를 들어 네트워크의 경우 WMI에서 라우터 구성을 관리할 수도 있을 것입니다. WMI에서 관리 객체(managed object)에 대한 정보를 얻는 응용 프로그램을 소비자(consumer)라고 합니다.소비자에게 관리 객체(managed object)는 공급자로 표시됩니다.

WMI 공급자는 관리 객체(managed object)의 정보를 유지 관리하고 WMI를 통해 소비자에게 전달하는 COM 구성 요소입니다.

공급자는 CIM에서 정의한 특정 인터페이스를 구현하여 WMI에 등록됩니다. 이러한 인터페이스를 구현함으로써 개발자는 필요에 따라 고유한 공급자를 작성할 수 있습니다. WMI는 표준 공급자라고 하는 미리 정의된 여러 공급자를 함께 제공합니다. 이 문서의 예제에서는 표준 공급자만 사용합니다.

그림 1이 이를 보여줍니다. 공급자들과의 상호 작용이 WMI에 의해 흐려져 표준 공급자와 사용자 지정 공급자가 사용자로부터 모두 숨겨집니다. WMI에 의해 노출된 데이터 구조는 운영 체제와 병합된 것처럼 보입니다.

관리 객체(managed object)에 대한 정보는 WMI 공급자가 만든 클래스의 인스턴스로 WMI에 의해 노출됩니다. 그러나 일반적으로 소비자는 이러한 인스턴스에 직접 액세스하지 않습니다. 대신 소비자가 WMI를 쿼리하면 WMI는 해당 공급자에게 쿼리를 전달합니다.

요청이 들어온 관리 객체(managed object)의 하위 집합 속성들에서 공급자는 다시 WMI를 통해 소비자에게 반환되는 결과 집합을 작성합니다(그림 2). 쿼리는 WMI의 요구 사항에 맞게 몇 가지 확장을 포함한 ANSI SQL의 하위 집합인 WQL로 정의 됩니다.

SQL과 WQL의 가장 중요한 차이점은 WQL이 읽기 전용 쿼리만 지원한다는 것입니다.

SQL에 익숙한 사용자에게 WQL은 이해할 수 있을만큼 매우 직관적입니다: 인스턴스의 속성을 쿼리하기 위해 속성 이름(인스턴스의 클래스에 의해 정의됨)이 클래스 이름을 테이블 이름으로 사용하여 SELECT 문에 열 이름으로 삽입됩니다. 예를 들어:

SELECT Name FROM Win32_Processor
 

위의 질의는 CPU 이름을 반환합니다. SQL과 마찬가지로 별표는 모든 열이 반환하라는 의미의 와일드카드입니다.쿼리 모드에 따라 결과는 ADO 또는 OLEDB와 매우 유사한 결과 집합으로 반환됩니다.

쿼리를 실행하는 모드는 세가지이며: 동기, 비동기 및 반동기 입니다.

처음 두 개는 정확히 이름에서 같은 의미로 이해가 되지만, 마지막은 하이브리드 특성을 말합니다:

쿼리는 유효한 결과 집합과 함께 즉시 반환되지만 집합의 내용, 즉 "실제" 결과는 나중에 WMI에 의해 채워집니다. 질의 모드를 어떤 것을 선택하는 것은 성능 및 보안에 영향을 미칩니다.

WQL 및 다양한 측면에 대한 보다 자세한 설명은 MSDN Library에서 찾을 수 있습니다.

 

II 동기화 질의문들

 

COM and WBEM Locator 설정

COM 기반 서비스를 호출하는 모든 프로세스 또는 스레드와 마찬가지로 WMI 소비자 작성의 첫 번째 단계는 CoInitializeEx를 호출하여 COM을 설정하는 것입니다.

일반적으로 WMI COINIT_MULTITHREADED 명시는 비동기 쿼리에 절대적으로 필요합니다.

이것은 호출 스레드는 resp. 프로세스를 다중 스레드 아파트로 넣어 처리 됩니다.

이 예외는 OLE 클라이언트들 입니다. 이 클라이언트들은 아파트 스레드 실행에서 제한됩니다.

이로 인해 섹션 II에서 다루게 되는 비동기 쿼리의 문제가 발생합니다.

적절한 시스템 전체 기본 보안 컨텍스트가 레지스트리에 설정되지 않은 경우 다음 단계는 CoInitializeSecurity를 ​​호출하여 프로세스 전체에서 설정하는 것입니다;

여기에서는 소비자만 고려하므로 설정할 매개 변수는 RPC_C_AUTHN_LEVEL_DEFAULT 및 RPC_C_IMPL_LEVEL_IMPERSONATE만 입니다.

대안으로는 CoInitializeSecurity가 이전에 부적절한 값으로 호출된 경우 CoSetProxyBlanket resp. 프록시별 설정에 대해 IClientSecurity::SetBlanket을 호출할 수 있습니다.

 

COM 및 COM 보안이 설정된 후 IWbemLocator 클래스를 사용하여 WMI 서비스에 액세스합니다.

CComPtr< IWbemLocator > locator;
HRESULT hr = CoCreateInstance( CLSID_WbemAdministrativeLocator, NULL,
                               CLSCTX_INPROC_SERVER, IID_IWbemLocator,
                               reinterpret_cast< void*** >( &locator ) );
 

IWbemLocator::ConnectServer는 WMI용으로 지정된 호스트에 연결을 합니다. 이 문서의 목적인 로컬 컴퓨터의 WMI 서비스가 사용됩니다.

IWbemLocator::ConnectServer는 다음과 같이 정의됩니다:

HRESULT ConnectServer( const BSTR strNetworkResource, const BSTR strUser,
                       const BSTR strPassword,const BSTR strLocale,
                       LONG lSecurityFlags, const BSTR strAuthority,
                       IWbemContext* pCtx, IWbemServices** ppNamespace )
 

첫 번째 매개 변수인 strNetworkResource는 소비자가 연결할 CIM 네임스페이스를 지정합니다.

C++ 네임스페이스와 마찬가지로 CIM 네임스페이스는 CIM 계층에서 이름을 명확하게 하고 그 위에 일부 문법 구조를 적용하는 데 사용됩니다.

이 문자열은 \\server\namespace1\namespace2... 또는 //server/namespace1/namespace2.... 형식이며, server는 네임스페이스가 속해 있는 시스템을 지정 합니다.

네임스페이스가 로컬 시스템에 있는 경우 server 는 생략할 수 있습니다. 즉, 네임스페이스 사양은 namespace1/namespace2... 또는 namespace1\namespace2...의 형식을 취합니다. root\default는 항상 정의되는 기본 네임스페이스를 지정합니다.사용자와 암호는 두 번째 및 세 번째 매개 변수로 전달됩니다. 로컬 시스템의 경우 NULL로 설정해야만 하고 혹은 호출이 실패 할 것입니다.

strLocale은 현재 로케일은 NULL인 로케일을 제공합니다.

lSecurityFlags는 일반적으로 WBEM_FLAG_USE_MAX_WAIT로 설정되어 2분 이내에 호출이 반환되도록 보장합니다. 이는 예를 들어 대상 시스템이 다운된 경우 무기한 차단 되는 것으로부터 소비자를 보호합니다.

strAuthority는 사용자를 인증할 Windows 도메인을 지정할 수 있습니다. 다시 말하지만 이것은 로컬 시스템에서는 NULL 혹은 strUser 매개변수내의 도메인을 지정 하는 것입니다.

공급자가 #IWbemContext 인스턴스를 필요로 하는 드문 경우를 제외하고 pCtx는 최종적으로 NULL로 설정됩니다. 대부분의 미리 정의된 WMI 구조의 네임스페이스는 root\CIMV2 네임스페이스내에 존재 합니다.

로컬 시스템의 경우 다음을 통해 연결이 설정됩니다:

CComPtr< IWbemServices > service;
hr = locator->ConnectServer( L"root\\cimv2", NULL, NULL, NULL,
                             WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &service );
 

WMI를 다룰 때, #WMI #API 는 wchar 기반 문자열을 사용해야 한다는 것을 염두에 두는 것이 중요합니다.

 

단순 질의문 - CPU 정보 질의하기(CPUTest 프로젝트)

이 하위 섹션에서는 WMI를 사용하는 - 입력 매개 변수가 없는 로컬 동기 쿼리 - 가장 간단한 시나리오를 다루겠습니다. 예를 들어, 로컬 CPU의 이름과 클록 주파수를 알아내야 하는 것입니다.

이 정보는 Win32_Processor 클래스의 인스턴스내의 WMI가 가지고 있습니다. 다양한 WMI 클래스, 특히 클래스가 소유하는 속성에 대한 자세한 내용은 MSDN Library를 참조하십시오.

이전 하위 섹션에서 설명한 대로 서비스가 성공적으로 설정되었다면, 이제 원하는 정보에 대한 WMI를 쿼리할 수 있습니다.

이 섹션은 동기 쿼리에 대한 내용이므로 IWbemServices::ExecQuery가 호출 합니다. 프로토타입은 다음과 같습니다:

HRESULT ExecQuery( const BSTR strQueryLanguage, const BSTR strQuery, LONG lFlags,
                   IWbemContext* pCtx, IEnumWbemClassObject** ppEnum )
 

첫 번째 매개변수인 strQueryLanguage는 질의문을 지정하며, 항상 L"WQL"로 설정되어야 합니다.

쿼리 자체에 대한 WQL 문은 strQuery로 전달합니다.

lFlags는 다양한 플래그를 지정하며 가장 중요한 플래그는 WBEM_FLAG_FORWARD_ONLY로 WMI가 오직 한 번만 전송 할 수 있는 결과 집합으로 열거형을 생성하도록 지시합니다.

이러한 열거형은 여러면에서 좀 더 효율적입니다. 나중에 관련 된 것이 나오는 다른 플래그에 대해서도 논의할 것입니다.

pCtx설명은 이전에 했던 내용과 같습니다. 결과 집합은 ppEnum의 열거형에 대한 포인터로 반환됩니다. 예를 들어:

CComPtr< IEnumWbemClassObject > enumerator;
hr = service->ExecQuery( L"WQL", L"SELECT * FROM Win32_Processor",
                         WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator );
 

Win32_Processor 클래스 인스턴스의 모든 속성에 대해 쿼리합니다. 결과 집합은 열거자로 반환됩니다.이런 결과가 포함된 열거형은 IEnumWbemClassObject::Next를 반복적으로 호출하여 순회할 수 있습니다.

이 메서드는 하나 이상의 IWbemClassObject 인스턴스를 반환할 수 있습니다. 앞에서 언급했듯이 이러한 인스턴스는 실제 WMI 관리 객체(managed object) 인스턴스가 아닙니다.

이 경우 Win32_Processor 클래스의 인스턴스가 될 것이며 대신 쿼리에서 요청한 속성에 대한 액세스를 구현하는 래퍼 역할을 합니다(그림 3).

하지만 그들은 서로를 식별할 수 있으며 문서의 나머지 부분의 적절한 곳에서 설명 할 것입니다.

열거형에서 반환되는 인스턴스 수는 쿼리에 지정된 클래스의 인스턴스 수, 즉 FROM 절에 대한 인수입니다. 일부 WMI 클래스는 한 번만 인스턴스화됩니다. 다른 것들은 여러 번 인스턴스화될 수도 있고 그렇지 않을 수도 있습니다.

예를 들어 Win32_Processor는 WMI 호스트에 설치된 각 CPU에 대해 인스턴스화됩니다. 즉, 단일 프로세서 시스템에는 하나의 인스턴스만 있고 다중 프로세서 시스템에는 둘 이상이 있을 수 있습니다.

두 번 이상 인스턴스화된 클래스의 경우 속성으로 이 인스턴스들을 구분할 수 있습니다. 부모클래스 이름이 FROM 절의 인수인 경우에도 마찬가지로 적용 됩니다.

이를 수행하는 방법은 다음 하위 섹션에서 설명 할 것입니다.

이와 관련하여 WMI를 처리할 때 IWbemClassObject는 소비자가 관리 객체(managed object)체의 데이터에 액세스하는 데 사용하는 유일한 인터페이스라는 점이 중요합니다.

물론 WMI 공급자를 작성할 때는 상황이 크게 달라 보일 것입니다.

IEnumWbemClassObject::Next는 다음 프로토타입을 가집니다:

HRESULT Next( LONG lTimeout, ULONG uCount, IWbemClassObject** ppObjects,
              ULONG* puReturned )
 

lTimeout은 결과 군의 결과가 사용 가능해질 때까지 기다리는 timeout(밀리초)을 지정합니다.

결과를 사용할 수 없는 상태에서 제한 시간이 만료되면 WBEM_S_TIMEDOUT이 반환됩니다.

WBEM_INFINITE는 무기한 timeout을 의미합니다.

동기 쿼리의 경우 결과가 있는 경우 항상 즉시 사용할 수 있으므로 이 매개변수는 사실상 무시됩니다.

다음 매개변수인 uCount는 ppObjects에서 최대로 반환될 것으로 예상되는 개체 수입니다. puReturned는 실제로 반환된 개체 수입니다.

ULONG retcnt;
CComPtr< IWbemClassObject > processor;
hr = enumerator->Next( WBEM_INFINITE, 1L, &processor, &retcnt );
 

따라서 프로세서 내의 Win32_Processor의 첫 번째 인스턴스를 반환합니다.

이 예제에서는 열거자에서 IWbemClassObject 인스턴스 하나만 추출되므로 편의상 CComPtr<>을 사용할 수 있습니다.

IEnumWbemClassObject::Next를 호출하여 둘 이상의 인스턴스를 추출할 때 일반 IWbemClassObject*의 배열을 전달해야 하며 이 후에 배열의 각 포인터에서 IUnknown::Release를 호출해야만 합니다.쿼리된 Win32_Processor 클래스 인스턴스의 속성들은 프로세서에서 반환되며 관심 있는 항목을 검색하는 데 사용됩니다.

이는 제공된 해당 속성의 이름으로 IWbemClassObject::Get을 호출하여 수행됩니다:

HRESULT Get( LPCWSTR wszName, LONG lFlags, VARIANT* pVal, CIMTYPE* pvtType,
             LONG* plFavor )
 

속성 값은 pVal의 VARIANT union 내로 반환됩니다. 여기서 _variant_t 래퍼 클래스를 사용할 수 있습니다. 속성 값과 함께 해당 CIM 유형 및 원본 정보가 반환될 수 있습니다.

예를 들어 CPU 이름은 다음과 같이 검색됩니다:

_variant_t var_val;
hr = obj->Get( L"Name", 0, &var_val, NULL, NULL );
 

쿼리에 인자 값 전달하기(LocalPing 프로젝트)

분명히 지금까지 제시된 다소 원시적인 WMI 쿼리 방법으로는 충분하지 않습니다.

주어진 기계에 설치된 CPU의 수는 적지만(보통) 예를들어 관리자 권한의 엔터티들 같은 다양한 관리 개체의 인스턴스들은 컴퓨터에 더 많은 수로 상주할 수 있습니다.

예를 들어 컴퓨터가 어떤 네트워크에 연결되는 즉시 네트워킹 인프라에 대한 정보는 처리해야만 합니다.여기에는 높은 수준의 네트워크 서비스 및 도구에서 낮은 수준의 프로토콜 스택에 이르는 모든 것이 포함될 수도 있습니다. WMI는 이러한 정보에 액세스할 수 있는 특정 클래스를 제공합니다.

한 가지 예는 잘 알려진 도구인 PING.EXE 입니다. 이 도구는 네트워크에서 주어진 IP 주소의 도달 가능성을 결정하는 데 사용됩니다.

PING.EXE에 대한 명령줄을 작성하고 exec 라이브러리 함수 중 하나를 통해 실행하는 대신 Win32_PingStatus 인스턴스에 대한 WMI에 간단히 질의할 수 있습니다.

물론 일반적으로 전체 인터넷이 아닌 매우 특정한 IP 주소를 핑하기를 원할 것입니다.

따라서 핑할 IP 주소는 어떤 방식으로든 WMI와 통신해야만 합니다.

대상 IP 주소는 Win32_PingStatus 클래스의 Address 속성을 통해 지정됩니다.

이는 WHERE 절로 쿼리의 SELECT 문을 확장하여 수행됩니다.

간단한 WHERE -절은 다음 형식 중 하나를 취합니다:

WHERE property operator constant
WHERE constant operator property
 

문법적으로 이것은 SQL 의미 체계와 매우 유사합니다. 주요 차이점은 SQL에서는 WHERE가 필터 역할을 하는 반면 WQL에서는 WHERE 절에 추가로 입력 인수를 지정할 수 있다는 것입니다. 다음 코드조각은 지정된 IP 주소(이 경우 로컬 루프백 인터페이스)를 ping하는 방법을 보여줍니다:

CComPtr< IEnumWbemClassObject > enumerator;
hr = service->ExecQuery( L"WQL", L"SELECT * FROM Win32_PingStatus " \
                         L"WHERE Address=\"127.0.0.1\"",
                         WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator );
 

ping 결과, 즉 대상 IP에 도달할 수 있는지 여부를 StatusCode 속성에 반환합니다. 값 0은 성공을 나타냅니다. 쿼리할 다른 WMI 클래스와 WHERE-clause를 제외하고 "LocalPing" 프로젝트의 연결된 소스 코드는 이전 하위 섹션의 샘플 코드와 거의 동일하게 작동하므로 더 논의할 필요는 없을 것입니다.

다음과 같이 식을 연산자와 결합하여 WMI에 대한 여러 인수를 지정할 수 있습니다:

CComPtr< IEnumWbemClassObject > enumerator;
hr = service->ExecQuery( L"WQL", L"SELECT * FROM Win32_PingStatus " \
                         L"WHERE ( Address=\"127.0.0.1\" ) " \
                         L"OR ( Address=\"192.168.1.1\" )",
                         WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator );
 

쿼리 결과를 검색할 때 이제 반환된 열거형에 둘 이상의 인스턴스가 포함된다는 점에 유의 해야 할 것입니다. WHERE 절에 대한 자세한 내용은 MSDN 또는 VS2003 온라인 설명서를 참조하십시오.

 

다중 WMI 클래스 동시 질의

때로는 더 나은 런타임 동작을 위해 두 개 이상의 쿼리를 한 번에 실행하는 것이 좋습니다.

SQL에서와 같이 FROM 절에 여러 클래스를 지정하는 직관적인 접근 방식은 WQL에서 지원되지 않습니다. 이를 해결하는 방법은 base 클래스의 인스턴스를 질의 후 클래스의 시스템 속성을 사용하여 결과를 제한하는 것입니다.

WMI 시스템 속성은 모든 클래스에 존재하는 유사 속성입니다. 다른 정보와 함께 그들의 목적은 반사 정보를 제공하는 것입니다.

예를 들어 __CLASS 속성에 액세스하여 인스턴스의 클래스 이름을 검색할 수 있습니다.

인스턴스가 단일 SELECT 문 내에서 질의되는 모든 클래스는 FROM 절에 지정된 직접 또는 간접의 공통 기본 클래스를 하나 이상 공유해야 합니다.

이는 base 클래스를 공유하지 않는 클래스는 이 방식으로 쿼리할 수 없음을 의미합니다.

 

예를 들어 #Win32_Keyboard 및 #Win32_PointingDevice 클래스의 인스턴스는 다음과 같이 쿼리할 수 있습니다:

SELECT * FROM CIM_UserDevice WHERE ( __CLASS="Win32_PointingDevice" )
                             OR ( __CLASS="Win32_Keyboard" )
 

일반적으로 반환된 열거형은 이기종간이 될 것입니다.

따라서 각 인스턴스에 올바른 속성 이름 등을 사용하도록 주의를 기울여야 합니다.

다시 말하지만 _CLASS 속성을 사용하여 클래스를 식별할 수 있습니다.

 

이상.

728x90