IT_Programming/WinForm (C#.NET)

닷넷 WMI를 통한 OS와의 상호 교류

JJun ™ 2007. 2. 12. 02:24
 

기본적으로 WMI는 하부 운영체제(윈도우XP이긴 하지만 윈도우 2000 등도 가능)와 상호 동작하는 데 필요한 매개체를 제공한다. 예전엔 그런 기능이 필요하면, 윈도우 API(Application Programming Interface)로 눈을 돌리는 수밖엔 없었다. 그러니 WMI는 축복인 셈이다.

 

WMI는 관리 기능을 제공한다. 윈도우 XP는 물론 이전 윈도우 버전에서도 이용 가능하다.

다만 이전 버전 윈도우에서는 기능을 모두 이용할 순 없지만 어느 정도는 쓸 수 있다.

System.Environment.dll 파일이 WMI 기능을 제공하며, 따라서 WMI를 사용하려면

이 파일은 닷넷 애플리케이션에 참조로서 추가돼야 한다.

또한 WMI는 하부 환경과 동작하기 위해 COM을 이용한다.

WMI 프로바이더는 WMI를 거쳐 이용되는 네이티브 윈도우 API 코드를 감싸고 있다.

프로바이더는 WMI 오브젝트 매니저에 의해 이용된다. 하부의 네이티브 API를 이용할 필요가 있다면

System.Environment 네임스페이스를 거쳐 WMI 오브젝트 매니저를 이용해 작업한다.

닷넷 프레임워크에는 공통 작업을 수행하는 데 사용되는 다양한 WMI 프로바이더가 포함돼 있다.

프로바이더의 예를 아래에 몇 가지 나열했다.

 

* 액티브 디렉토리 프로바이더: 액티브 디렉토리에 접근을 허용한다.

   이 프로바이더는 윈도우 2000부터 지원된다.

* 설정 프로바이더: 사용자들이 닷넷 CLR(Common Language Runtime)을 설정할 수 있도록 한다.

   닷넷 프레임워크에 포함되어 있다.

* 디스크 쿼타 프로바이더: 디스크 쿼타를 제어할 수 있게 한다. XP부터 지원된다.

* 이벤트 로그 프로바이더: 이벤트 로그(Event Log)에 액세스할 수 있도록 한다. NT 이상에서 지원된다.

* 성능 카운터 프로바이더: 성능 카운터에 액세스할 수 있도록 한다. 2000부터 지원된다.

* 시스템 레지스트리 프로바이더: 레지스트리(Registry)에 액세스할 수 있도록 한다. NT부터 지원된다.

* Win32 프로바이더: 환경 변수에 액세스할 수 있도록 한다. 2000부터 지원된다.

   커스텀 프로바이더를 제작할 수도 있다. 윈도우 ME부터 윈도우 운영체제에 WMI가 포함되었지만

   윈도 버전에 따라 이용할 수 있는 프로바이더가 다르다. MS는 WMI 관리 도구를 제공하며 이 도구를

   이용해서 어떤 프로바이더를 쓸 수 있는지 살펴볼 수 있다.

 

 

본격적인 WMI 이용하기

이제 WMI에 관한 일반적인 내용과 WMI의 기능에 대해 알았으니, 닷넷 코드로 WMI의 장점을 시험적으로 이용해 보자. 전에 언급했듯 프로젝트에서 System.Environment.dll에 대한 참조를 추가해야 한다.

또한 코드 안에 System.Environment 네임스페이스를 포함해야 한다. C#에서는 Using을, J#에서는 import를, VB닷넷에서는 Imports를 사용한다. 다음 예제는 여러 시스템 프로퍼티에 액세스하는 코드의 예이다.

 

using System;

using System.Management;

namespace Builder

{

   class WMIExample

   {

      [STAThread]

       static void Main(string[] args)

       {

           try

           {

               ManagementObject mo = new ManagementObject

                                                    ("Win32_ComputerSystem.Name=\"PENTIUM4\"");

               Console.WriteLine("Description: " + mo["Description"].ToString());

               Console.WriteLine("Model: " + mo["Model"].ToString());

               Console.WriteLine("Number of processors: " +

               mo["NumberOfProcessors"].ToString());

            }

            catch (ManagementException e)

            {

                 Console.WriteLine("Exception encountered: " + e.ToString());

            }

            catch (Exception e)

            {

                 Console.WriteLine("Exception encountered: " + e.ToString());

            }

       }

   }

}

 

VB닷넷으로는 다음과 같이 작성한다.:

Imports System.Management

Module Module1

Sub Main()

Try

Dim mo As ManagementObject

mo = New ManagementObject("Win32_ComputerSystem.Name=""PENTIUM4""")

Console.WriteLine("Description: " + mo("Description").ToString())

Console.WriteLine("Model: " + mo("Model").ToString())

Console.WriteLine("Number of processors: " + mo("NumberOfProcessors").ToString())

Catch e As ManagementException

Console.WriteLine("Management exception encountered: " + e.ToString())

Catch e As Exception

Console.WriteLine("Exception encountered: " + e.ToString())

End Try

End Sub

End Module

 

코드를 좀 자세히 살펴보자. 우선 ManagementObject 클래스의 인스턴스는 WMI와 동작하는 데

사용된다. WMI를 통해 액세스 가능한 어떤 객체와도 동작하도록 ManagementObject 클래스를

사용할 수 있다.

WMI 클래스(Win32_ComputerSystem.Name="Pentium")는 ManagementObject 객체를 인스턴스화하는 데 사용된다. 대상 시스템에서 WMI 클래스를 이용할 수 있는지 알아보기 위해 전에 언급한 WMI 관리 도구(WMI 오브젝트 브라우저)를 사용할 수 있다. 정보를 추가하는 것뿐 아니라 값을 수정할 수도 있다.

다음에 나타낸 예제 코드에서는 하드 드라이브에 할당된 이름을 변경한다.

 

using System;

using System.Management;

namespace Builder

{

   class WMIExample

   {

      [STAThread]

      static void Main(string[] args)

      {

         try

         {

            ManagementObject mo = new ManagementObject("Win32_LogicalDisk.DeviceID=\"F:\"");

            mo.Get();

            mo["VolumeName"] = "FDrive";

            mo.Put();

         }

         catch (ManagementException e)

         {

               Console.WriteLine("Exception encountered: " + e.ToString());

         }

         catch (Exception e)

         {

               Console.WriteLine("Exception encountered: " + e.ToString());

         }

      }

   }

 }

 

VB닷넷으로 작성하면 다음과 같다.

Imports System.Management

Module Module1

Sub Main()

Try

Dim mo As ManagementObject

mo = New ManagementObject("Win32_LogicalDisk.DeviceID=""F:""")

mo.Get()

mo("VolumeName") = "New Volume"

mo.Put()

Catch e As ManagementException

Console.WriteLine("Management exception encountered: " + e.ToString())

Catch e As Exception

Console.WriteLine("Exception encountered: " + e.ToString())

End Try

End Sub

End Module

 

이 예제는 처음 것과 유사하다. 차이점이라면 드라이브 이름 프로퍼티가 변경됐다는 것이다. get 메소드는 변경 전에 호출돼야 한다. 이렇게 해야 확실히 WMI 인스턴스가 드라이브의 현재 상태로 정확히 초기화된다. 새 이름이 할당된 후 하부 오브젝트를 업데이트하기 위해 put 메소드가 호출된다. (주의: 변경 사항을 확실히 저장하기 바란다.)

WMI는 닷넷 프레임워크의 중요 측면이지만 거의 주목을 받지 못하고 있다. WMI는 애플리케이션이 동작하는 다양한 측면의 환경과 상호 동작하고 이 환경에 조작을 가할 수 있다. 또한 이벤트를 통해 시스템의 변화 같은 것을 모니터링하는 것이 가능할 수도 있다.@


Tony Patton ( Builder.com )

[ 저작권자 ⓒ ZDNet Korea, CNET Korea,Inc. 무단 전재 및 재배포 금지, ZDNet Korea는 글로벌 IT 미디어 리더 CNET Networks의 브랜드입니다. ]