Открыть почтовый клиент по умолчанию вместе с вложением

Привет, я работаю над WPF-приложением (используя c #).

Мне нужно иметь функциональность, в которой пользователи могут отправлять файлы (аудиофайлы) в виде вложений по электронной почте. Я попытался использовать пространство имен Microsoft.Office.Interop.Outlook.Application но он открывает внешний вид и не работает, если Outlook не установлен на компьютере клиента.

Я пробовал использовать SmtpClient() и SmtpClient() пространства имен System.Net.Mail но не открывал почтовый клиент. Его отправка почты через предопределенный сервер (может быть, проблема, поскольку я не знаю, что мой домен электронной почты по умолчанию для моего клиента. Эта ссылка имеет все, что мне нужно, и ее работоспособность.

Но там они использовали атрибут DllImport, и из этого метода может возникнуть множество проблем (из чего я могу понять). Я понятия не имею о управляемом и неуправляемом коде, поэтому я не могу понять, в чем проблема. Хорошо ли следовать примеру в приведенной выше ссылке. Если не так?

Можете ли вы рассказать или предоставить ссылки о том, как подойти к моей проблеме?

Мы можем использовать тот факт, что большинство почтовых клиентов поддерживают формат файла .EML для загрузки.

Поэтому, если мы расширим class System.Net.Mail.MailMessage таким образом, чтобы его можно было сохранить в файловой системе в виде файла .EML. Полученный файл можно открыть почтовым клиентом по умолчанию, используя Process.Start (имя файла)

Для правильной работы мы должны добавить строку, содержащую «X-Unsent: 1» в файл .EML. Эта строка сообщает клиенту электронной почты о загрузке файла .EML, сообщение должно быть представлено в режиме «Новое сообщение».

Используйте параметр bool «addUnsentHeader» метода расширения, чтобы добавить эту строку в файл .EML

Метод расширения выглядит следующим образом:

 using System; using System.IO; using System.Net.Mail; using System.Reflection; namespace Fsolutions.Fbase.Common.Mail { public static class MailUtility { //Extension method for MailMessage to save to a file on disk public static void Save(this MailMessage message, string filename, bool addUnsentHeader = true) { using (var filestream = File.Open(filename, FileMode.Create)) { if (addUnsentHeader) { var binaryWriter = new BinaryWriter(filestream); //Write the Unsent header to the file so the mail client knows this mail must be presented in "New message" mode binaryWriter.Write(System.Text.Encoding.UTF8.GetBytes("X-Unsent: 1" + Environment.NewLine)); } var assembly = typeof(SmtpClient).Assembly; var mailWriterType = assembly.GetType("System.Net.Mail.MailWriter"); // Get reflection info for MailWriter contructor var mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null); // Construct MailWriter object with our FileStream var mailWriter = mailWriterContructor.Invoke(new object[] { filestream }); // Get reflection info for Send() method on MailMessage var sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic); sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { mailWriter, true, true }, null); // Finally get reflection info for Close() method on our MailWriter var closeMethod = mailWriter.GetType().GetMethod("Close", BindingFlags.Instance | BindingFlags.NonPublic); // Call close method closeMethod.Invoke(mailWriter, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { }, null); } } } } 

Используйте метод расширения следующим образом:

  var mailMessage = new MailMessage(); mailMessage.From = new MailAddress("[email protected]"); mailMessage.Subject = "Your subject here"; mailMessage.IsBodyHtml = true; mailMessage.Body = "My HTML formatted body"; mailMessage.Attachments.Add(new Attachment("C://Myfile.pdf")); var filename = "C://Temp/mymessage.eml"; //save the MailMessage to the filesystem mailMessage.Save(filename); //Open the file with the default associated application registered on the local machine Process.Start(filename); 

Пробовали ли вы использовать System.Diagnostics.Process.Start() с соответствующей командной строкой?

 mailto:[email protected]?subject=an email&body=see attachment&attachment="/files/audio/attachment.mp3" 

Переключатель &attachment позволяет указать имя файла.

Хорошо, я изо всех сил стараюсь работать, но, возможно, это можно сделать. Я сейчас читаю этого монстра и вернусь к вам.

Вы можете попросить оболочку Windows открыть URL-адрес mailto:

 var url = "mailto:[email protected]"; Process.Start(url); 

Вы должны using System.Diagnostics .

Вы можете установить различные части сообщения, такие как объект и тело, как описано в RFC 6068

 var url = "mailto:[email protected]?subject=Test&body=Hello"; 

К сожалению, протокол mailto не поддерживает вложения, даже если некоторые клиенты электронной почты могут иметь способ их обработки.

Я использовал следующий вспомогательный class.

 class MAPI { public bool AddRecipientTo(string email) { return AddRecipient(email, HowTo.MAPI_TO); } public bool AddRecipientCC(string email) { return AddRecipient(email, HowTo.MAPI_TO); } public bool AddRecipientBCC(string email) { return AddRecipient(email, HowTo.MAPI_TO); } public void AddAttachment(string strAttachmentFileName) { m_attachments.Add(strAttachmentFileName); } public int SendMailPopup(string strSubject, string strBody) { return SendMail(strSubject, strBody, MAPI_LOGON_UI | MAPI_DIALOG); } public int SendMailDirect(string strSubject, string strBody) { return SendMail(strSubject, strBody, MAPI_LOGON_UI); } [DllImport("MAPI32.DLL")] static extern int MAPISendMail(IntPtr sess, IntPtr hwnd, MapiMessage message, int flg, int rsv); int SendMail(string strSubject, string strBody, int how) { MapiMessage msg = new MapiMessage(); msg.subject = strSubject; msg.noteText = strBody; msg.recips = GetRecipients(out msg.recipCount); msg.files = GetAttachments(out msg.fileCount); m_lastError = MAPISendMail(new IntPtr(0), new IntPtr(0), msg, how, 0); if (m_lastError > 1) MessageBox.Show("MAPISendMail failed! " + GetLastError(), "MAPISendMail"); Cleanup(ref msg); return m_lastError; } bool AddRecipient(string email, HowTo howTo) { MapiRecipDesc recipient = new MapiRecipDesc(); recipient.recipClass = (int)howTo; recipient.name = email; m_recipients.Add(recipient); return true; } IntPtr GetRecipients(out int recipCount) { recipCount = 0; if (m_recipients.Count == 0) return IntPtr.Zero; int size = Marshal.SizeOf(typeof(MapiRecipDesc)); IntPtr intPtr = Marshal.AllocHGlobal(m_recipients.Count * size); int ptr = (int)intPtr; foreach (MapiRecipDesc mapiDesc in m_recipients) { Marshal.StructureToPtr(mapiDesc, (IntPtr)ptr, false); ptr += size; } recipCount = m_recipients.Count; return intPtr; } IntPtr GetAttachments(out int fileCount) { fileCount = 0; if (m_attachments == null) return IntPtr.Zero; if ((m_attachments.Count <= 0) || (m_attachments.Count > maxAttachments)) return IntPtr.Zero; int size = Marshal.SizeOf(typeof(MapiFileDesc)); IntPtr intPtr = Marshal.AllocHGlobal(m_attachments.Count * size); MapiFileDesc mapiFileDesc = new MapiFileDesc(); mapiFileDesc.position = -1; int ptr = (int)intPtr; foreach (string strAttachment in m_attachments) { mapiFileDesc.name = Path.GetFileName(strAttachment); mapiFileDesc.path = strAttachment; Marshal.StructureToPtr(mapiFileDesc, (IntPtr)ptr, false); ptr += size; } fileCount = m_attachments.Count; return intPtr; } void Cleanup(ref MapiMessage msg) { int size = Marshal.SizeOf(typeof(MapiRecipDesc)); int ptr = 0; if (msg.recips != IntPtr.Zero) { ptr = (int)msg.recips; for (int i = 0; i < msg.recipCount; i++) { Marshal.DestroyStructure((IntPtr)ptr, typeof(MapiRecipDesc)); ptr += size; } Marshal.FreeHGlobal(msg.recips); } if (msg.files != IntPtr.Zero) { size = Marshal.SizeOf(typeof(MapiFileDesc)); ptr = (int)msg.files; for (int i = 0; i < msg.fileCount; i++) { Marshal.DestroyStructure((IntPtr)ptr, typeof(MapiFileDesc)); ptr += size; } Marshal.FreeHGlobal(msg.files); } m_recipients.Clear(); m_attachments.Clear(); m_lastError = 0; } public string GetLastError() { if (m_lastError <= 26) return errors[m_lastError]; return "MAPI error [" + m_lastError.ToString() + "]"; } readonly string[] errors = new string[] { "OK [0]", "User abort [1]", "General MAPI failure [2]", "MAPI login failure [3]", "Disk full [4]", "Insufficient memory [5]", "Access denied [6]", "-unknown- [7]", "Too many sessions [8]", "Too many files were specified [9]", "Too many recipients were specified [10]", "A specified attachment was not found [11]", "Attachment open failure [12]", "Attachment write failure [13]", "Unknown recipient [14]", "Bad recipient type [15]", "No messages [16]", "Invalid message [17]", "Text too large [18]", "Invalid session [19]", "Type not supported [20]", "A recipient was specified ambiguously [21]", "Message in use [22]", "Network failure [23]", "Invalid edit fields [24]", "Invalid recipients [25]", "Not supported [26]" }; List m_recipients = new List(); List m_attachments = new List(); int m_lastError = 0; const int MAPI_LOGON_UI = 0x00000001; const int MAPI_DIALOG = 0x00000008; const int maxAttachments = 20; enum HowTo { MAPI_ORIG = 0, MAPI_TO, MAPI_CC, MAPI_BCC }; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public class MapiMessage { public int reserved; public string subject; public string noteText; public string messageType; public string dateReceived; public string conversationID; public int flags; public IntPtr originator; public int recipCount; public IntPtr recips; public int fileCount; public IntPtr files; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public class MapiFileDesc { public int reserved; public int flags; public int position; public string path; public string name; public IntPtr type; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public class MapiRecipDesc { public int reserved; public int recipClass; public string name; public string address; public int eIDSize; public IntPtr entryID; } 

Используйте class MAPI как MAPI ниже.

 MAPI mapi = new MAPI(); mapi.AddAttachment("c:\\temp\\file1.txt"); mapi.AddAttachment("c:\\temp\\file2.txt"); mapi.AddRecipientTo("[email protected]"); mapi.AddRecipientTo("[email protected]"); mapi.SendMailPopup("testing", "body text"); // Or if you want try and do a direct send without displaying the // mail dialog mapi.SendMailDirect("testing", "body text"); 

Ссылка: Код проекта

  • Изменение вида для ViewModel
  • Синхронизированная прокрутка двух ScrollViewer, когда любой прокручивается в wpf
  • Как скрыть столбцы datagrid wpf в зависимости от свойства
  • Как использовать фоновый рабочий стол WPF
  • Как преобразовать цвет в кисть в XAML?
  • Исключение (исключения) задачи не наблюдалось ни при ожидании задачи, ни при доступе к ее свойству Exception. В результате необнаруженное исключение было
  • Введите ключевой обработчик события
  • Плавная текстовая анимация (Marquee) с использованием WPF
  • Почему обновление привязки не реализует INotifyPropertyChanged?
  • Можете ли вы получить доступ к элементам пользовательского интерфейса из другого streamа? (не задано)
  • Как я могу программно генерировать события нажатия клавиш на C #?
  • Interesting Posts

    LibreOffice Writer: скопировать из поиска «Найти все» и вставить в список

    Ошибка: в этом контексте поддерживаются только примитивные типы или типы перечислений EF

    Отображать клавиатуру без анимации

    Каков наилучший способ parsingа форматированного файла с фиксированной шириной в Java?

    Как использовать ffmpeg для downmix 5.1 DTS HD MA или Dolby TrueHD для стерео AAC с Dolby Pro Logic II?

    Фильтрация строк данных.файла по логическому условию

    андроид на прослушивателе изменения текста

    Как Intel HD Graphics от процессоров 2010 года сравнивается с текущими низкоуровневыми видеокартами?

    Принудительное применение для перезапуска при первом действии

    Объясните, какое правило gitignore игнорирует мой файл

    Как протестировать веб-сервис Джерси REST?

    Как запросить вложенные объекты?

    Прозрачный полый или вырезанный круг

    Действительно ли «Неопределенное поведение» действительно позволяет * что-либо * произойти?

    Форматы сжатия с хорошей поддержкой случайного доступа в архивах?

    Давайте будем гением компьютера.