Использование функций MAPI из управляемого кода официально не поддерживается. По-видимому, MAPI использует свое собственное управление памятью, и он аварийно завершает свою работу в управляемом коде (см. Здесь и здесь ).
Все, что я хочу сделать, это запустить почтовый клиент по умолчанию с темой, телом и одним или несколькими вложениями .
Итак, я смотрел в MAPISendDocuments, и, кажется, работает. Но я не смог набраться смелости, чтобы реально использовать эту функцию в рабочем коде.
Кто-нибудь часто использовал эту функцию? У тебя есть какие-нибудь ужасные истории?
PS. Нет, я не буду shellExecute Outlook.exe с аргументами командной строки для вложений.
PPS. Поддержка вложений является обязательным требованием , поэтому Mailto: решения для меня не подходят.
Иметь отдельный вспомогательный EXE-файл, который принимает параметры командной строки (или канал к его StandardInput), который делает то, что требуется, и вызывать это из основного приложения. Это сохраняет материал MAPI вне пространства процессов вашего основного приложения. Хорошо, вы все еще смешиваете MAPI и .NET, но в очень коротком процессе. Предполагается, что MAPI и CLR начинают вызывать проблемы с более длительными процессами.
Мы используем превосходную библиотеку Дмитрия Стребленченко Redemption Data Objects, которая позволяет нам писать такой код «shim» на JScript и вызывать его, который хранит миры CLR и MAPI в отдельных процессах, но поддерживаемым способом.
@Chris Fournier re. написание неуправляемой DLL. Это не будет работать, потому что проблема заключается в смешивании MAPI и управляемого кода в одном процессе .
Вызов process.Start по протоколу Mailto: (как показано ниже) даст вам базовые функциональные возможности, но не вложения.
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 из управляемого кода.
Вы также можете использовать Outlook Redemption , который поддерживается из управляемого кода; Я не сразу уверен, если у него есть простая замена MAPISendDocuments, но Дмитрий полезен, если у вас есть вопросы.
Что касается "сбоев и ожогов", вот еще одна цитата от парня из службы поддержки MS, здесь
Это то, что в основном будет работать. Это сработает, пока ты это пишешь. Тогда это будет работать, пока вы его тестируете. Это будет работать, пока ваш клиент оценивает его. Тогда как только заказчик его развернет - БАМ! Вот когда это решит начать иметь проблемы. И Microsoft не собирается помогать вам с этим, так как мы сказали вам не делать этого в первую очередь. :)
Я сделал это с помощью функции MAPISendMail и нескольких внутренних классов, чтобы обернуть некоторые другие связанные с MAPI структуры. Пока это единственное использование, его можно безопасно выполнять, хотя это и не тривиально, поскольку требует очень пристального внимания к различным неуправляемым типам данных и распределению / освобождению памяти и GC. Хотя это все еще не поддерживается, я использую это в производственном коде (хотя это еще не отправлено).
Когда я спросил об этом Мэтта Стела, я получил ответ:
Я действительно не знаю гораздо лучшего способа сделать это, и любые проблемы, с которыми вы здесь столкнулись, возможно, будут воспроизводиться в поддерживаемом сценарии (например, VB6 или неуправляемый C ++). Просто знайте, что если вы когда-нибудь столкнулись со сценарием, если проблема была вызвана именно этой функцией, вызываемой из .NET, у нас не было бы никакой другой рекомендации, чтобы вы не использовали .NET.
Не совсем то, чтобы использовать его, но также не говоря о том, что есть и другие варианты сделать это из управляемого кода.
Для тех, кто имеет опыт работы с MAPI, им потребуется меньше времени, чтобы разобраться в коде, чтобы сделать именно то, что вы хотите от неуправляемого кода (читай: простой C ++), чем набирать этот пост и читать ответ (без обид).
Вам повезло, функциональность, в которой вы нуждаетесь, ограничена. Все, что вам нужно, - это простая утилита C ++, которая принимает необходимые параметры в командной строке и выполняет правильные вызовы MAPI. Затем вы извлекаете всю эту утилиту из своего управляемого кода так же, как вы выполняете любой другой процесс.
НТН
MAPISendDocuments устарела и может быть удалена. Вместо этого вы должны использовать MAPISendMail. Смотрите простой MAPI
Следующий код не использует 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);