MAPI и опыт управляемого кода? [закрыто]

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

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

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

Кто-нибудь часто использовал эту функцию? У тебя есть какие-нибудь ужасные истории?

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

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

7.08.2008 07:56:24
Спасибо за вопрос и ссылки! Поиск информации о MAPI / Managed Code помог мне сэкономить время разработчиков.
SkullDuggerT 29.10.2008 17:40:39
8 ОТВЕТОВ
РЕШЕНИЕ

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

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

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

8
1.09.2008 20:26:46

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

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

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

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

1
8.08.2008 11:09:42

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

1
20.08.2008 20:01:35

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

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

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

1
27.08.2008 15:26:23
Я думаю, что постер имел в виду управляемые приложения, оказывающие существенную нагрузку на MAPI. Простой вызов MAPISendMail по запросу пользователя вряд ли приведет к таким же проблемам.
Yuhong Bao 15.09.2011 06:17:53

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

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

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

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

1
31.08.2008 00:43:06

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

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

НТН

-3
4.04.2009 05:46:25
Есть ли шанс, что вы сможете проверить код и опубликовать его здесь?
JoshL 17.11.2010 00:42:12

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

2
18.05.2014 00:00:22

Следующий код не использует 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);
0
10.12.2010 11:58:19