| Home | People | COM | Emulation |
|---|---|---|---|
| Python |
윈도우즈 2000에서 파이썬과 COM을 가지고 놀고 있는 중이다. PythonWin 내장 도움말에서 어느 정도는 COM과 다양한 공통 인터페이스에 대하여 괴상한 세부정보를 설명하고 있지만, 구체적인 인터페이스 정보를 찾으러 가는 것이 정말 필요하다. 몇가지 정보의 소스가 있으나, 이 문서의 목적은 독자들이 그런 자원을 사용하는 것을 돕거나, 또는 그런 자원을 사용할 필요조차 없도록 돕는 것이다.
파이썬을 윈도우즈용으로 얻는 가장 쉬운 방법은 ActiveState에 가서 ActivePython 꾸러미를 내려받는 것이다. 다른 방법으로는 파이썬 사이트에 가서 파이썬을 내려 받은 다음 (윈도우즈 지원 파이썬 페이지 참조) win32all 확장을 찾아 보는 것이다 (더 자세한 정보는 마크 해몬드(Mark Hammond)의 윈도우즈 확장 파이썬 페이지를 참조). 물론, 나는 그냥 쉬운 방법을 택했다!
아래에 보여준 일을 하려면, 마이크로소프트 아웃룩 같은 소프트웨어가 또 필요하다. 이미 그런 소프트웨어를 가지고 있아서, 아웃룩을 가지고 노는데 관심이 없을지라도 말이다.
짜증나게도 마이크로소프트 익스체인지 서버는 많은 내부 정보를 감추고 있어서 약속 일정과 주소록같은 것들을 얻으려면 상당량의 프로그래밍을 요구한다. 흥미롭게도 다른 시스템의 주소록을 익스체인지로 반입하는 방법에 관해서는 조언이 아주 많지만 반대로 다른 것으로의 반출에 관해서는 별로 조언이 없다. 다행스럽게도, 마이크로소프트사는 충분히 많은 API를 제공하여 자신이 "해결책"이 된다. 왜냐하면 이 API는 내부정보에 접근하여 잠겨있는 정보를 추출하는 데 합리적인 메커니즘을 제공하기 때문이다.
어쨌든, 이 때문에 나는 작은 프로그램을 작성하여 아웃룩을 통하여 익스체인지 메시지 목록과 약속일정에 접근하게 되었다. 회사에서 익스체인지를 운영하고 있다면, 아마도 Outlook도 실행시켜야 할텐데, 그러면 아웃룩을 자동화하는 것이 익스체인지에 접근하는 좋은 전략이다. 특정 유형의 정보에 접근하는 한가지 대안은 액티브 디렉토리(Active Directory) 서비스 API나 LDAP를 사용하는 것이지만, 나는 그 분야를 잘 모른다.
주의: 이 어플리케이션을 시작하기 전에, "Microsoft Outlook 9.0 Object Library"를 구축하자. "COM Makepy utility"를 사용하면 된다 ("Type Libraries" 초기화하기 참조).
Outlook Explorer 프로그램은 (이 프로그램은 여기에서 내려받을 수 있다) MAPI (Messaging API)를 Outlook 안에서 사용하여 메일 자원에 접근한다. 객체 계통도를 항해하려면 간단한 명령어-줄 인터페이스를 사용하여, 파일시스템의 기존 디렉토리에 대한 정보를 추출하면 된다.
win32com 꾸러미는 COM 인터페이스를 질의하고 접근하는 데 수 많은 방식을 제공한다. (인터페이스를 알고 있다면) 그들 사이에 별 차이가 없다. 보통 (특히 속성 완성 기능을 갖춘 PythonWin 안에서) 실험할 때는 어느 메쏘드와 특성이 실제로 주어진 인터페이스에 대하여 사용가능한지 아는 것이 더 편리하다. 이곳에서 "COM Makepy utility"가 사용된다. PythonWin의 "Tools" 메뉴에 있다. 특별한 유형의 라이브러리를 선택하고 이 도구를 이용하여 파이썬 인터페이스를 구축하면, PythonWin에서 더욱 더 많은 정보를 얻을 수 있고 객체 인터페이스를 대략 조사하기가 더욱 더 쉬워진다.
모든 클라이언트 COM 접근은 파이썬 프로그램에서 다음 서술문으로 시작한다:
import win32com.client
전형적으로, 그러면 프로그램은 사용할 객체를 찾으려고 시도한다. 예를 들어:
object = win32com.client.Dispatch("Outlook.Application")
이 객체는 그러면 "COM 객체"를 참조한다. 이 객체는 다른 메쏘드와 속성들을 가질 수 있어서 다른 파이썬 객체들처럼 요청하고 조사할 수 있다. 물론 이렇게 할 때 (아웃룩같은) 윈도우즈 어플리케이션을 "자동화" 시켜야 한다.
일단 어플리케이션을 "자동화해주는" 객체에 대한 참조점을 확보하면, 다음으로 할 일은 객체 계통도의 루트를 찾는 일이다. 거기에 모든 흥미로운 정보가 저장된다. Outlook 어플리케이션의 자동화 객체로, 제일 쉽게 이를 달성하는 방법은 MAPI 이름공간에 들어가는 것이다:
ns = object.GetNamespace("MAPI")
이렇게 하면 Outlook 안에서 접근이 가능한 "folder" 계통도에 접근할 수 있다. 이 계통도를 직접 볼 수 있다.Outlook을 수동으로 열고 폴더 메뉴를 띄운다 (전형적으로 "Inbox"나 "Outlook Today" 등등이 씌여있다).
ns 객체는 이제 보통의 파이썬 객체처럼 취급이 가능하다. 이 객체에는 객체 계통도의 다른 부분들로 인도하는 특별한 속성을 가지고 있다.
Outlook Explorer 프로그램은 환상적인 파이썬 트릭을 사용하여 자신이 참조하는 "COM 객체들"의 속성에 접근한다. 그러나, 본질적으로 각 객체 안의 폴더와 항목들을 찾아본다:
# 주어진 객체 안에서 폴더들 참조하기... ns_list = ns.Folders # 주어진 객체 안에서 항목들 참조하기... ns_list = ns.Items
이제, 어떻게 각 객체의 세부사항을 조사할 것인가? 예를 들어, 어떻게 한 폴더의 이름에 접근할 수 있는가? 먼저, 그 객체가 보여주는 인터페이스를 알아야 한다. 이 정보는 여러 곳에서 찾아 볼 수 있다:
win32com/gen_py 디렉토리에 "grep" 검색을 수행하면 된다. 또는 그 인터페이스 파일의 이름이 무엇인지 보려면 그 인터페이스를 가진 객체에 엉터리 메쏘드를 요청하거나 거기에 존재하지 않는 속성에 접근하면 된다.
그렇지만, 희망적이게도 접근중인 그 객체는 PythonWin에서 잘 알고 있어서 속성이나 메쏘드 완성 기능을 사용할 수 있다. 필요한 메쏘드나 속성에 관하여 좀 더 자세한 정보가 필요하면 위에 언급한 방법에 의존해야 한다. 다음과 같이 시도해 볼 수도 있다:
dir(object.__class__)
폴더의 이름은 다음과 같이 접근할 수 있다:
object.Name # 이곳에서 객체가 폴더를 참조한다.
물론, 폴더 안에는 폴더나 항목들이 많이 있을 수 있다. 어떻게 이 집단들을 순회할까? 권장하는 방식은 거의 틀림없이 파이썬의 연속열 인덱스 표기법을 사용하는 것이지만, 주의하자: 첫 요소의 인덱스는 표준이 아니며 0 또는 1이 될 수 있다. 아웃룩의 객체 모델에서, 그런 연속열의 첫 인자는 실제로 인덱스가 1이며, 관찰 결과는 다음과 같다:
len(object)에서 34를 받으면 마지막 요소는 인덱스가 33이 아니고 - 34이다. 아주 파이썬 스럽지 못하지만, 실제로 이에 관하여 할수 있는 일이 별로 없다.
연속열처럼 행위하는 객체에 접근하기 위하여, 다음과 같은 파이썬 메커니즘이 사용된다:
object[1] # 첫 요소. len(object) # 요소의 개수를 돌려준다.
다음 메커니즘은 작동하지 않는 듯 하다:
object[-1] # 마지막 요소여야 하지만, 대신에 예외가 일어난다. object[1:4] # 연속열을 조각썰기해야 하지만, 대신에 예외가 일어난다.
위의 정보를 가지고, 예제 프로그램은 다양한 수준의 폴더에 접근하고 항목들을 질의하며 그리고 정보를 추출할 수 있다. 주어진 폴더에 Parent 속성을 사용하면, 계통도를 따라 위로 항해할 수 있다. 이미 탐험한 곳들을 기록 유지할 필요가 없이 말이다.