Опыт работы с MAPI и управляемым кодом?[закрыто]
Вопрос
Использование функций MAPI из управляемого кода официально не поддерживается.По-видимому, MAPI использует свое собственное управление памятью, и он выходит из строя и записывается в управляемом коде (см. здесь и здесь)
Все, что я хочу сделать, это запустить почтовый клиент по умолчанию с субъектом, телом, И одно или несколько вложений.
Итак, я изучал MAPISendДокументы и, кажется, это работает.Но я так и не смог набраться смелости, чтобы действительно использовать эту функцию в производственном коде.
Кто-нибудь часто пользовался этой функцией?У вас есть какие-нибудь страшилки?
PS.Нет, я не буду использовать ShellExecute Outlook.exe с аргументами командной строки для вложений.
ППС.Поддержка прикрепления - это требование , так что Отправляйте почту:решения не подходят для меня.
Решение
Имейте отдельный вспомогательный EXE-файл, который принимает параметры командной строки (или передает их в StandardInput), который выполняет то, что требуется, и вызывает это из вашего основного приложения.Это позволяет сохранить содержимое MAPI за пределами пространства процессов вашего основного приложения.Хорошо, вы все еще смешиваете MAPI и .NET, но это очень недолговечный процесс.Предполагается, что MAPI и среда CLR начинают вызывать проблемы с более длительными процессами.
Мы используем превосходную технику Дмитрия Стреблеченко Объекты данных о погашении библиотека, которая позволяет нам писать такой "промежуточный" код на JScript и вызывать его, который сохраняет миры CLR и MAPI в отдельных процессах, но поддерживаемым способом.
@Крис Фурнье повторно.написание неуправляемой библиотеки DLL.Это не сработает, потому что проблема заключается в смешивании MAPI и управляемого кода в том же процессе.
Другие советы
MAPISendDocuments устарел и может быть удален.Вместо этого вам следует использовать MAPISendMail.Видишь Простой MAPI
Вызывающий процесс.Запустите на Почтовое отправление:протокол (как показано ниже) предоставит вам базовую функциональность, но не вложения.
Process.Start("mailto:name@domain.com?subject=TestCode&Body=Test Text");
Вы можете использовать этот подход с путями вложений, но этот параметр работает только с некоторыми старыми версиями Outlook, такими как 98.Я предполагаю, что это связано с потенциальным риском безопасности.
Если кто-либо использует outlook.exe он будет выдавать предупреждения безопасности в Outlook 2003 (и 2007 в зависимости от настроек).
Вы должны быть в состоянии создать неуправляемую библиотеку DLL, которая выполняет нужные вам операции с помощью MAPI, а затем вызвать эту библиотеку DLL из вашего управляемого кода.Я бы не стал писать прямую оболочку MAPI, но что-то, что выполняет все функции, которые вам требуются от MAPI, содержащиеся в этой неуправляемой библиотеке DLL.Вероятно, это был бы самый безопасный способ использования MAPI из управляемого кода.
Вы также могли бы использовать Погашение перспективы, который поддерживается из управляемого кода;Я не сразу уверен, есть ли в нем простая замена MAPISendDocuments, но Дмитрий будет полезен, если у вас возникнут вопросы.
Что касается "сбоев и ожогов", вот еще одна цитата из службы поддержки MS, здесь
Это как раз то, что в основном работает.Это будет работать, пока вы это пишете.Тогда это будет работать, пока вы его тестируете.Это будет работать, пока ваш клиент оценивает это.Затем, как только клиент развертывает его - БАЦ!Вот тогда-то он и решит начать испытывать проблемы.И Microsoft не собирается помогать вам в этом, поскольку мы с самого начала говорили вам не делать этого.:)
Я сделал это, используя функцию MAPISendMail и несколько внутренних классов, чтобы обернуть некоторые другие структуры, связанные с MAPI.Пока это единственное применение, это возможно, хотя и нетривиально, сделать безопасно, поскольку это требует очень пристального внимания к различным неуправляемым типам данных и распределению / освобождению памяти и GC.Хотя это все еще не поддерживается, я использую это в производственном коде (хотя оно еще не отправлено).
Когда я спросил Мэтта Штеле об этом, ответ, который я получил, был:
Я действительно не знаю гораздо лучшего способа сделать это, и любые проблемы, с которыми вы столкнулись здесь, вероятно, были бы воспроизводимы в поддерживаемом сценарии (т. Е.VB6 или неуправляемый C++).Просто знайте, что если вы когда - либо сталкивались со сценарием, проблема была вызвана именно этой функцией , вызываемой из.NET, что у нас не было бы для вас никаких других рекомендаций, кроме как не использовать .NET.
Не совсем удачное использование, но и не говорю, что есть какие-либо другие варианты, чтобы действительно сделать это из управляемого кода.
Следующий код не использует 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);
Для кого-то, кто имеет опыт работы с MAPI, потребовалось бы меньше времени, чтобы доработать код, чтобы делать именно то, что вы хотите, из неуправляемого кода (читать:обычный C ++), чем печатать этот пост и читать ответ (без обид).
Вам повезло, что необходимая вам функциональность ограничена.Все, что вам нужно, - это простая утилита на C ++, которая возьмет нужные вам параметры из командной строки и выполнит правильные вызовы MAPI.Затем вы используете эту утилиту из своего управляемого кода точно так же, как вы бы выполняли любой другой процесс.
HTH