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. Embora a ajuda incorporada no PythonWin vá de alguma forma para explicar os detalhes estranhos da COM e das várias interfaces comuns que se pode encontrar, é realmente necessário procurar uma interface concreta em formação. Existem algumas fontes de tais informações, e o objetivo deste documento é ajudar os leitores a usar tais fontes, ou mesmo a ajudá-los a evitar a necessidade de usar essas fontes.
Pré-requisitos
Talvez a maneira mais fácil de obter plataformas Python para Windows é ir para o ActiveState e baixar seu pacote ActivePython. Você pode, alternativamente, visitar o site Python, baixar o Python (consulte o suporte Python para a página do Windows) e depois procurar as extensões win32all
consulte a página Python para Extensões do Windows de Mark Hammond para obter detalhes). Eu simplesmente fiz o que foi mais fácil, é claro!
Para as atividades a seguir, você pode precisar de software adicional, como o Microsoft Outlook, embora você provavelmente não esteja interessado em jogar com o Outlook e o Exchange, se você não possui.
Outlook e Exchange
Uma das coisas supostamente irritantes sobre o Microsoft Exchange Server é a forma como ele oculta muitos dos seus internos e exige uma quantidade razoável de programação para que você possa chegar a coisas como listas de contatos e livros de endereços. É interessante notar que é necessário encontrar muitos conselhos sobre como importar os livros de endereços de outros sistemas para o Exchange, mas não tanto em obter as endereços de volta e em outra coisa. Felizmente, a Microsoft fornece o suficiente de uma API para se tornar sua própria "destruição", uma vez que esta API fornece um mecanismo razoável para acessar os internos e extrair a informação encriptada.
De qualquer forma, isso me levou a escrever um pequeno programa para acessar listas de mensagens, contatos e compromissos do Exchange através do Outlook. Se sua organização estiver executando o Exchange, provavelmente você também precisa executar o Outlook 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 dos Serviços do Active Directory e/ou o LDAP, mas não fui bem sucedido naquela área.
Exemplo: Outlook Explorer
Nota: Antes de iniciar esta aplicação, crie "Microsoft Outlook 9.0 Object Library" usando o "COM Makepy utility" (consulte "Initialising Type Libraries").
O programa Outlook Explorer (que você pode fazer o download) usa MAPI (Messaging API) no Outlook para acessar recursos de email. Você pode navegar a hierarquia de objetos usando uma interface de linha de comando simples 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 interfaces COM com poucas diferenças óbvias entre elas (desde que conheça a interface), geralmente é mais conveniente ao experimentar (particularmente no PythonWin com seu recurso de conclusão de atributos) para saber quais métodos e as propriedades estão realmente disponíveis para uma determinada interface. Aqui é útil o utilitário "COM Makepy", acessível no menu "Ferramentas" no PythonWin. Ao selecionar uma biblioteca de tipos específicos e construir as interfaces Python usando esta ferramenta, muito mais informações ficam disponíveis no PythonWin, e a investigação casual das interfaces de objetos torna-se muito fácil.
Escrevendo clientes
Todo o acesso COM do cliente começa com a seguinte declaração no seu programa Python:
import win32com.client
Normalmente, seu programa tentará e achará um objeto a ser usado. Por exemplo:
object = win32com.client.Dispatch("Outlook.Application")
Este objeto 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.
Encontrando a Raiz de 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 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 esta hierarquia, abrindo o Outlook manualmente e trazendo o menu da pasta (que tipicamente diz "Caixa de entrada" ou "Outlook hoje" ou algo assim).
O objeto ns
agora pode ser tratado como um objeto Python normal, com atributos especiais que levam a outras partes da hierarquia de objetos.
Pastas e Itens
O programa do Outlook Explorer usa alguns truques sofisticados do Python para acessar os atributos dos "objetos COM" que ele faz referência, mas na essência procura as pastas e itens disponíveis em cada objeto:
# Refer para as pastas com um dado objeto... ns_list = ns.Folders # Refer para os itens com um dado objeto... ns_list = ns.Items
Consultando Interfaces
Agora, como investigar o detalhe de cada objeto? Por exemplo, como um 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 documentação da API da Microsoft.
- Outras fontes úteis, como a documentação do "Outlook Exchange".
- 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 diretório
win32com/gen_py
dentro da sua distribuição Python, ou invoque um método incorreto ou acesse um atributo inexistente em um se aponte para essa interface para ver qual é o nome do arquivo da interface. - O "OLE / COM Object Viewer" no menu "Ferramentas" no Microsoft Visual C ++ (pelo menos no Visual Studio 6.
- Uma vez aberta, a seção "Interfaces" da hierarquia de informações pode ser explorada para revelar algumas entradas "_Application". Para um desses, o painel de informações mencionará "Microsoft Outlook 9.0 Object Library" em "TypeLib", por exemplo.
- Clicando 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 "Bibliotecas de tipos" da hierarquia de informações listará, por exemplo, "Microsoft Outlook 9.0 Object Library", e isso pode ser investigado clicando duas vezes naquela entrada.
Felizmente, no entanto, o objeto que você está acessando é conhecido o bastante pela PythonWin para permitir algum tipo de atributo ou conclusão do método nele. Você só precisa recorrer ao acima quando um conhecimento mais detalhado sobre um método ou atributo é necessário. Você também pode tentar algo como:
dir(object.__class__)
O nome de uma pasta pode ser acessado da seguinte maneira:
Object.nome # onde o objeto refere-se a uma pasta.
Sequências
Claro, pode haver muitas pastas ou itens em uma pasta. Como atravessamos essa coleção? A maneira recomendada é argumentar usar a notação do índice de seqüência do Python, mas cuidado: o índice do primeiro elemento aparentemente não é padrão e pode ser 0 ou 1. No modelo de objeto do Outlook, o primeiro elemento em tais sequências é de fato indexado por 1, resultando no seguintes observações:
- O comprimento da seqüência, enquanto correto, não pode ser "diminuído" para fornecer o índice do último elemento. Por exemplo, se
len(object)
dá34
, então o último elemento não tem o índice 33 - tem o índice 34. Muito não-Pythonic, podemos reivindicar, mas aparentemente não há nada que realmente possa ser feito sobre isso. - O "primeiro elemento Pythonic" (elemento 0) não existe.
Para acessar objetos que se comportam como seqüências, os seguintes mecanismos Python podem ser usados:
object[1] # O primeiro elemento. len(object) # Retornar o número de elementos.
Os seguintes mecanismos não parecem funcionar:
object[-1] # Deve ser o último elemento, mas em vez disso, obtém uma exceção. object[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. Ao usar o atributo
Parent
em qualquer pasta, podemos navegar para cima através da hierarquia sem precisar manter referências a locais que já exploramos.