Pergunta

O uso de funções MAPI no código gerenciado não é oficialmente suportado.Aparentemente, o MAPI usa seu próprio gerenciamento de memória e trava e queima dentro do código gerenciado (veja aqui e aqui)

Tudo o que quero fazer é iniciar o cliente de e-mail padrão com sujeito, corpo, E um ou mais anexos.

Então eu estive pesquisando MAPISenviarDocumentos E parece que funciona.Mas não consegui reunir coragem para realmente usar a função no código de produção.

Alguém já usou muito essa função?Você tem alguma história de terror?

PS.Não, não executarei o ShellExecute Outlook.exe com argumentos de linha de comando para anexos.

PPS.O suporte de anexo é um requerimento , então Mailto:soluções não são suficientes para mim.

Foi útil?

Solução

Tenha um EXE auxiliar separado que receba parâmetros de linha de comando (ou canalize para seu StandardInput) que faça o que é necessário e chame-o de seu aplicativo principal.Isso mantém o material MAPI fora do espaço de processo do seu aplicativo principal.OK, você ainda está misturando MAPI e .NET, mas em um processo de curta duração.A suposição é que o MAPI e o CLR começam a causar problemas em processos de execução mais longa.

Usamos o excelente trabalho de Dmitry Streblechenko Objetos de dados de resgate biblioteca que nos permite escrever esse código "shim" em JScript e invocá-lo, o que mantém os mundos CLR e MAPI em processos separados, mas de forma suportada.

@Chris Fournier re.escrevendo uma DLL não gerenciada.Isso não funcionará porque o problema é misturar MAPI e código gerenciado no mesmo processo.

Outras dicas

MAPISendDocuments está obsoleto e pode ser removido.Você deve usar MAPISendMail.Ver MAPI simples

Processo de chamada. Comece no Correio:protocolo (conforme mostrado abaixo) fornecerá funcionalidades básicas, mas não anexos.

Process.Start("mailto:name@domain.com?subject=TestCode&Body=Test Text");

Você pode fazer essa abordagem com caminhos de anexo, mas esta opção só funciona com algumas versões antigas do Outlook, como a 98.Presumo que isso se deva ao risco potencial de segurança.

Se alguém usar o Outlook.exe, ele emitirá avisos de segurança no Outlook 2003 (e no 2007 Dependente das configurações).

Você deve ser capaz de criar uma DLL não gerenciada que execute as operações desejadas usando MAPI e, em seguida, invocar essa DLL a partir do seu código gerenciado.Eu não escreveria um wrapper MAPI direto, mas algo que execute todas as funcionalidades necessárias do MAPI contidas nessa DLL não gerenciada.Essa provavelmente seria a maneira mais segura de usar MAPI em código gerenciado.

Você também pode usar Resgate do Outlook, que é compatível com código gerenciado;Não tenho certeza se ele possui uma substituição simples de MAPISendDocuments, mas Dmitry é útil se você tiver dúvidas.

Quanto a "travamentos e queimaduras", aqui está outra citação de um cara de suporte da MS, aqui

É o tipo de coisa que funciona principalmente.Funcionará enquanto você o escreve.Então funcionará enquanto você o testa.Funcionará enquanto seu cliente o avalia.Então, assim que o cliente o implantar – BAM!É aí que decidirá começar a ter problemas.E a Microsoft não vai te ajudar com isso, já que dissemos para você não fazer isso em primeiro lugar.:)

Fiz isso usando a função MAPISendMail e várias classes internas para agrupar algumas das outras estruturas relacionadas ao MAPI.Contanto que este seja o único uso, é possível, embora não trivial, fazê-lo com segurança, pois requer muita atenção aos vários tipos de dados não gerenciados e à alocação/desalocação de memória e GC.Embora ainda não seja compatível, estou usando isso no código de produção (embora ainda não tenha sido enviado).

Quando perguntei a Matt Stehle sobre isso, a resposta que recebi foi:

Eu realmente não conheço uma maneira muito melhor de fazer isso e quaisquer problemas que você encontre aqui provavelmente seriam reproduzíveis em um cenário suportado (ou seja,VB6 ou C++ não gerenciado).Apenas saiba que se você já se deparou com um cenário em que um problema foi causado especificamente por essa função ser chamada do .NET, não teríamos nenhuma outra recomendação para você do que não usar o .NET.

Não é exatamente uma bênção usá-lo, mas também não estou dizendo que existem outras opções para realmente fazer isso a partir do código gerenciado.

O código a seguir não usa MAPI como tal, mas abre a janela "Escrever e-mail" com anexos arbitrários.

(na verdade, não foi testado, mas descobri em um aplicativo que acredito ter funcionado)

using Microsoft.Office;
using Microsoft.Office.Core;

...

Outlook.Application outlook = new Outlook.Application();
Outlook.MailItem mail = (Outlook.MailItem) outlook.CreateItem(Outlook.OlItemType.olMailItem);

mail.BodyFormat = Outlook.OlBodyFormat.olFormatRichText;
mail.HTMLBody = "stuff";
mail.Subject = "more stuff";
string file = File.ReadAllBytes(...);
mail.Attachments.Add(file, Outlook.OlAttachmentType.olByValue, 1, file)

mail.Display(false);

Para alguém experiente com MAPI, levaria menos tempo para gerar o código para fazer exatamente o que você deseja do código não gerenciado (leia-se:C++ simples) do que digitar esta postagem e ler a resposta (sem ofensa).

Você tem sorte de que a funcionalidade necessária é limitada.Tudo o que você precisa é de um utilitário C++ simples para pegar os parâmetros necessários na linha de comando e emitir as chamadas MAPI corretas.Em seguida, você tira todo esse utilitário do seu código gerenciado, assim como faria para executar qualquer outro processo.

HTH

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top