본문 바로가기

WMI

WMI를 사용하여 프로그램 삭제하기

글은 아래의 글을 번역한 겁니다.

http://www.codeproject.com/Tips/428199/Uninstalling-applications-programmatically-with-WM


Introduction

최근에 나는 application을 프로그램으로 삭제하려했다. 많은 개발자들이 registry key 접근방법으로 지우려하는것을 인터넷을 뒤져서 알았다.(uninstall string을 찾아서 Windows installer에게 전달해 주는것 )

그라나 이러한 방법은 많은 단점들이 있다. uninstall string이 어디있는지 그리고 OS(86x,64x)에 따라서 그위치가 틀릴수 있기 때문이다. 그리하여 WMI를 사용하여 이러한 문제를 해결하려 한다.


Using the code

문저 System.Management COM을 참조한다. 그리고 아래와 같이 사용할 네임스페이스를 기입한다.

using System.Management


Listing installed applications

다음으로 설치된 applicaiton의 목록들을 가져온다.(어떤 항목들은 Win32_Product에 속해 있어서 uninstall string이 없을수 있다. 그럼으로 add/remove program리스트에도 안나올수 있다) 

리스트를 가져오는 첫번째 단계로 ManagementObjectSearcher 생성함으로 management objects들의 항목들을 특정 쿼리로 가져온다. 우리가 할 쿼리는 Win32_Product class를 이용한 쿼리이다.

ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");

쿼리를 셋팅한 다음에 커멘드를 샐행할 필요가 있다. 그렇게 하기 위해서 ManagementObjectSearcher Get() 함수를 사용한다.

Get() 함수는 매우강력한 자원이다. 이것은 어떤한 값을 리턴시켜준다.

foreach (ManagementObject mo in mos.Get())
{
 ///

Get() 함수는 IEnumerable을 리턴해 줌으로 우리는 컨텐츠를 루핑을 시킨다.  그리고 각 항목들은 ManagementObject로 된다. 우리는 단순히 여기서 "Name"속성을 볼것이다.

우리는 다음과 같은 포맷으로 ManagementObject의 프로퍼티를 얻게 될것이다.

mo["Name"].ToString()

위의 값은 Object 이기 때문에 우리는 string으로 컨버팅해줘야한다. C#에선 매우 간단하다.

다음은 모든 코드이다.


using System.Management
private List<string> ListPrograms()
{
    List<string> programs = new List<string>();

    try
    {
        ManagementObjectSearcher mos = 
          new ManagementObjectSearcher("SELECT * FROM Win32_Product");
        foreach (ManagementObject mo in mos.Get())
        {
            try
            {
                //more properties:
                //http://msdn.microsoft.com/en-us/library/windows/desktop/aa394378(v=vs.85).aspx
                programs.Add(mo["Name"].ToString());

            }
            catch (Exception ex)
            {
                //this program may not have a name property
            }
        }

        return programs;

    }
    catch (Exception ex)
    {
        return programs;
    }
}


Uninstalling an application

이제 삭제하는 시간이다. 삭제 메서드는 우리가 인스톨된 프로그램을 가져온 메서드와 거의 유사하다. 유일한 차이점은 우리가 Win32_Product 메서드를 호출해 줘서 “Uninstall”해야한다는 것이다.

쿼리가 조금바뀐다. 위에서 우리는 이미 어떤 프로그램이 설치되어있는지 알수 있다. 이제 우리는 모든 것을 

열거할 필요가 없다:

"SELECT * FROM Win32_Product WHERE Name = '" + ProgramName + "'"

아래는 모든 코드를 보여준다.

 private bool UninstallProgram(string ProgramName)
{
    try
    {
        ManagementObjectSearcher mos = new ManagementObjectSearcher(
          "SELECT * FROM Win32_Product WHERE Name = '" + ProgramName + "'");
        foreach (ManagementObject mo in mos.Get())
        {
            try
            {
                if (mo["Name"].ToString() == ProgramName)
                {
                    object hr = mo.InvokeMethod("Uninstall", null);
                    return true;
                }
            }
            catch (Exception ex)
            {
                //this program may not have a name property, so an exception will be thrown
            }
        }

        //was not found...
        return false;

    }
    catch (Exception ex)
    {
        return false;
    }
}

mos.Get()이 실행되고 나서 우리는 삭제할 프로그램의 리스트를 갖게 될것이다. . 이제 삭제할 메서드에 초점을 맞춰보자.

object hr = mo.InvokeMethod("Uninstall", null);


이제 우리의 ManagementObject  가 application의 인스턴스로 셋팅되고 우리는 그 application을 삭제하길 원한다. 그리하여 Win32_Product class의 "Uninstall"를 호출한다. 위의 코드는 어떻게 메서드를 호출하는지 설명하고 있다. 




===끝=== 오랜만에 번역하려니까 힘드네요 실제로 돌려보니 잘 되네요....

모두한번 돌려보시길