Возможности MAPI и управляемого кода?

Использование функций MAPI из управляемого кода официально не поддерживается. По-видимому, MAPI использует собственное управление памятью, и он дает сбой и сгорает в управляемом коде (см. Здесь и здесь )

Все, что я хочу сделать, это запустить почтовый клиент по умолчанию с темой, телом и одним или несколькими вложениями .

Итак, я изучал MAPISendDocuments, и, похоже, он работает. Но я не смог набраться смелости, чтобы использовать эту функцию в производственном коде.

Кто-нибудь много использовал эту функцию? У вас есть какие-нибудь страшилки?

PS. Нет, я не буду использовать shellExecute Outlook.exe с аргументами командной строки для вложений.

PPS. Поддержка вложений является обязательным требованием , поэтому решения Mailto: не подходят для меня.

Ответов (8)

Решение

Имейте отдельный вспомогательный EXE-файл, который принимает параметры командной строки (или передает его StandardInput), который выполняет то, что требуется, и вызывает его из вашего основного приложения. Благодаря этому материалы MAPI останутся за пределами рабочего пространства вашего основного приложения. Хорошо, вы все еще смешиваете MAPI и .NET, но это очень недолговечный процесс. Предполагается, что MAPI и CLR начинают вызывать проблемы с более длительными процессами.

Мы используем превосходную библиотеку Redemption Data Objects Дмитрия Стреблченко, которая позволяет нам писать такой «прокладочный» код на JScript и вызывать его, который сохраняет миры CLR и MAPI в отдельных процессах, но поддерживаемым образом.

@Chris Fournier re. написание неуправляемой DLL. Это не сработает, потому что проблема заключается в смешивании MAPI и управляемого кода в одном процессе .

MAPISendDocuments устарел и может быть удален. Вместо этого вам следует использовать MAPISendMail. См. Простой MAPI

Вызов процесса. Запуск по протоколу Mailto: (как показано ниже) предоставит вам базовую функциональность, но не вложения.

Process.Start("mailto:[email protected]?subject=TestCode&Body=Test Text");

Вы можете использовать этот подход с путями вложений, но этот вариант работает только с некоторыми старыми версиями Outlook, такими как 98. Я предполагаю, что это связано с потенциальным риском безопасности.

Если кто-то использует outlook.exe, он выдаст предупреждения о безопасности в Outlook 2003 (и 2007 в зависимости от настроек).

Вы должны иметь возможность создать неуправляемую DLL, которая выполняет нужные вам операции с помощью MAPI, а затем вызывать эту DLL из управляемого кода. Я бы не стал писать прямую оболочку MAPI, но что-то, что выполняет все функции, которые требуются от MAPI, содержащиеся в этой неуправляемой DLL. Вероятно, это был бы самый безопасный способ использовать MAPI из управляемого кода.

Вы также можете использовать Outlook Redemption , который поддерживается управляемым кодом; Я не сразу уверен, есть ли у него простая замена MAPISendDocuments, но Дмитрий поможет, если у вас есть вопросы.

Что касается «сбоев и ожогов», вот еще одна цитата из службы поддержки MS, здесь

Это то, что в основном сработает. Он будет работать, пока вы его пишете. Тогда он будет работать, пока вы его тестируете. Он будет работать, пока ваш клиент его оценивает. Тогда как только заказчик развернет - БАМ! Вот тогда он решит, что у него начнутся проблемы. И Microsoft не собирается вам в этом помогать, поскольку мы изначально говорили вам не делать этого. :)

Я сделал это с помощью функции MAPISendMail и нескольких внутренних классов, чтобы обернуть некоторые другие структуры, связанные с MAPI. Пока это единственное использование, это возможно, хотя и не тривиально, сделать безопасно, поскольку это требует очень пристального внимания к различным неуправляемым типам данных и распределению / освобождению памяти и сборке мусора. Хотя он все еще не поддерживается, я использую его в производственном коде (хотя он еще не отправлен).

Когда я спросил об этом Мэтта Стеле, я получил следующий ответ:

Я действительно не знаю лучшего способа сделать это, и любые проблемы, с которыми вы здесь столкнулись, вероятно, были бы воспроизведены в поддерживаемом сценарии (например, VB6 или неуправляемом C++). Просто знайте, что если вы когда-либо сталкивались с ситуацией, когда проблема была вызвана именно тем, что эта функция вызывалась из .NET, у нас не было бы никаких других рекомендаций для вас, чтобы вы не использовали .NET.

Не совсем удачно использовать его, но я также не говорю, что есть какие-то другие варианты, чтобы на самом деле сделать это из управляемого кода.

Для кого-то, имеющего опыт работы с MAPI, им потребуется меньше времени на то, чтобы набрать код, чтобы делать именно то, что вы хотите от неуправляемого кода (читай: простой C++), чем на ввод этого сообщения и чтение ответа (без обид).

Вам повезло, что нужная вам функциональность ограничена. Все, что вам нужно, это простая утилита C++, которая принимает нужные вам параметры в командной строке и выполняет правильные вызовы MAPI. Затем вы можете использовать всю эту утилиту из своего управляемого кода, как если бы вы выполняли любой другой процесс.

HTH

Следующий код не использует MAPI как таковой, но открывает окно «Написать письмо» с произвольными вложениями.

(на самом деле, это совершенно не тестировалось, но я откопал его в приложении, которое, как мне кажется, работало)

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);