Original Article: Python and COM
Author: Paul Boddie

Python and COM

Home Pessoas COM Emulação
Python

Resumo

Tenho jogado com Python e COM no Windows 2000. Enquanto a integração ajude PythonWin a explicar de alguma forma os detalhes bizarros de COM e as várias interfaces comuns que se pode encontrar, é realmente necessário ir à procura de informações concretas da interface. Existem algumas fontes de tais informações, e o objetivo deste documento é ajudar os leitores a usar essas fontes, ou mesmo ajudá-los a evitar a necessidade de usar tais fontes.

Pré-requisitos

Talvez a forma mais fácil de obter plataformas Python para Windows seja ir para Estado Ativo e baixar seu pacote ActivePython. Você também pode visitar o site Python, fazer o download do Python Suporte ao Python para Windows pagina) e depois ir à procura do win32all Extensões (ver Mark Hammond Python para extensões do Windows para obter detalhes). Acabei de fazer o que era mais fácil, é claro!

Para as atividades abaixo, você pode precisar de software extra, como o Microsoft Outlook, embora você provavelmente não estará interessado em jogar com o Outlook e o Exchange, se você não tiver.

Outlook e Exchange

Uma das coisas supostamente irritantes sobre o Microsoft Exchange Server é a maneira que ele esconde um monte de seus internos e requer uma quantidade razoável de programação para deixá-lo chegar a coisas como listas de contatos e livros de endereços. É interessante notar que muitos conselhos podem ser encontrados na importação de outros livros de endereços para o Exchange, mas não tanto na obtenção de endereços para fora e em outra coisa. Felizmente, a Microsoft fornece o suficiente de uma API para se tornar seu próprio "desfazendo", uma vez que esta API fornece um mecanismo razoável para acessar os internos e extrair as informações bloqueadas.

Enfim, isso me levou a escrever um pequeno programa para acessar listas de mensagens do Exchange, contatos e compromissos através do Outlook. Se sua organização estiver executando o Exchange, provavelmente você precisará executar o Outlook também e, portanto, automatizar o Outlook é uma estratégia válida para acessar o Exchange. Uma alternativa para acessar certos tipos de informações é usar a API de Serviços do Diretório Ativo e/ou LDAP, mas não tenho êxito nessa área.

Exemplo: Outlook Explorer

Nota: Antes de iniciar este aplicativo, crie o "Microsoft Outlook 9.0 Object Library" usando o "utilitário COM Makepy" (consulte "Inicializando bibliotecas de tipos").

O programa Explorer do Outlook (que você pode baixar) Usa MAPI (Messaging API) dentro do Outlook para acessar recursos do email. Você pode navegar pela hierarquia de objetos usando uma simples interface de linha de comando e extrair informações para diretórios existentes no sistema de arquivos.

Atividades

Inicializando bibliotecas de tipos

Embora o pacote win32com forneça várias maneiras de consultar e acessar as interfaces COM com poucas diferenças óbvias entre elas (desde que você conheça a interface), geralmente é mais conveniente ao experimentar (particularmente no PythonWin com seu recurso de preenchimento de atributos) saber quais métodos e propriedades estão realmente disponíveis para uma determinada interface. É aqui que o utilitário "COM Makepy", acessível a partir do menu "Ferramentas" no PythonWin, é útil. Selecionando uma biblioteca de tipos específica e construindo as interfaces Python usando esta ferramenta, muito mais informações ficam disponíveis no PythonWin, e a investigação casual de interfaces de objetos torna-se muito mais fácil.

Escrevendo Clientes

Todo o acesso COM do cliente começa com a seguinte instrução no seu programa Python:

importar win32com.client

Normalmente, o programa irá tentar encontrar um objeto para usar. Por exemplo:

objeto = win32com.client.Dispatch("Outlook.Application")

Este objeto irá então se referir a um "objeto COM", que pode ter métodos invocados sobre ele e seus atributos examinados como qualquer outro objeto Python, embora possamos estar "automatizando" um aplicativo do Windows (como o Outlook) quando fazemos isso.

Localizando a raiz da hierarquia de objetos

Uma vez que temos uma referência a um objeto que está "automatizando" um aplicativo, a próxima coisa a fazer é encontrar a raiz da hierarquia de objetos onde todas as informações interessantes são armazenadas. Com o objeto de automação do aplicativo do Outlook, a maneira mais fácil de conseguir isso é inserir o namespace MAPI:

ns = object.GetNamespace("MAPI")

Isso nos permite acessar a hierarquia "pasta" acessível no Outlook. Você pode ver essa hierarquia você mesmo abrindo o Outlook manualmente e exibindo o menu de pastas (que normalmente diz "Caixa de entrada" ou "Outlook hoje" ou algo assim).

O objecto ns pode agora ser tratado como um objeto normal Python, com atributos especiais levando a outras partes da hierarquia de objetos.

Pastas e Itens

O programa Explorer do Outlook usa alguns truques de Python extravagantes para acessar os atributos dos "objetos COM" que ele faz referência, mas na essência ele procura as pastas e itens disponíveis dentro de cada objeto:

# Consulte as pastas dentro de um determinado objeto...
ns_list = ns.Folders
# Consulte os itens dentro de um determinado objeto...
ns_list = ns.Items

Consultando Interfaces

Agora, como se investiga o detalhe de cada objeto? Por exemplo, como se acessa o nome de uma pasta? Em primeiro lugar, ajuda a conhecer a interface que o objeto expõe e essa informação pode ser encontrada em vários locais:

  • A API documentação da Microsoft .
  • Outras fontes úteis, como o "Intercâmbio do Outlook" documentação.
  • O arquivo de interface gerado pelo "utilitário COM Makepy". Para saber qual arquivo é relevante para a interface em questão, execute uma pesquisa "grep" para o nome da interface no win32com/gen_py na sua distribuição Python ou invoque um método errado ou acesse um atributo inexistente em um objeto com essa interface para ver qual é o nome do arquivo de interface.
  • O "OLE / COM Object Viewer" no menu "Ferramentas" no Microsoft Visual C ++ (pelo menos no Visual Studio 6.0).
    • Uma vez aberta, a sessão "Interfaces" da hierarquia de informações pode ser explorada para revelar algumas entradas "_Application". Para um destes, o painel de informações irá mencionar "Microsoft Outlook 9.0 Object Library" em "TypeLib", por exemplo.
    • Clicar duas vezes em uma entrada "_Application" fornecerá um "ITypeInfo Viewer" que contém uma seção "_Methods" descrevendo os métodos disponíveis no objeto de automação do aplicativo.
    • A seção "Tipo Bibliotecas" da hierarquia de informações listará, por exemplo, "Microsoft Outlook 9.0 Object Library", e isso pode ser investigado clicando duas vezes nessa entrada.

Esperemos que, no entanto, o objeto que você está acessando é bem conhecido por PythonWin para permitir algum tipo de atributo ou método de conclusão sobre ele. Você só precisa recorrer ao método acima quando um conhecimento mais detalhado sobre um método ou atributo é necessário. Você também pode tentar algo como isto:

dir(object.__class__)

O nome de uma pasta pode ser acessado da seguinte forma:

Object.nome # onde o objeto refere-se a uma pasta.

Sequências

Claramente, podem haver muitas pastas ou itens em uma pasta. Como nós percorremos essa coleção? O modo recomendado é provavelmente usar a sequência de notação do índice de Python, mas cuidado: o índice do primeiro elemento aparentemente não é padrão e pode ser 0 ou 1. No objeto modelo do Outlook, o primeiro elemento em tais sequências é de fato indexado por 1, resultando nas seguintes observações:

  • O comprimento da sequência, embora correto, não pode ser "decrementado" para fornecer o índice do último elemento. Por exemplo, se len(object)34, então o último elemento não tem o índice 33 - tem o índice 34. Muito não-Pythonic, poderíamos alegar, mas aparentemente não há nada que realmente possa ser feito sobre ele.
  • O "primeiro elemento Pythonic" (elemento 0) não existe.

Para acessar objetos que se comportam como sequências, os seguintes mecanismos Python podem ser usados:

objeto[1]   # O primeiro elemento.
len(objeto) # Retornar o número de elementos.

Os seguintes mecanismos não parecem funcionar:

objeto[-1]  # Deve ser o último elemento, mas em vez disso, obtém uma exceção.
objeto[1:4] # Deve cortar a sequência, mas em vez disso, obtém uma exceção.

Resumo

Com as informações acima, o programa de exemplo pode acessar diferentes níveis de pastas, itens de consulta e extrair informações. Usando o atributo Pai em qualquer pasta, podemos navegar para cima através da hierarquia sem a necessidade de manter referências a lugares que já exploraram.