C# 是否有一种使用默认邮件客户端发送带有附件的电子邮件的简单方法?
我的问题是,我需要将带有C的文件附加到默认邮件客户端,并将其显示给用户,就像使用C# 是否有一种使用默认邮件客户端发送带有附件的电子邮件的简单方法?,c#,mapi,email-client,email-attachments,C#,Mapi,Email Client,Email Attachments,我的问题是,我需要将带有C的文件附加到默认邮件客户端,并将其显示给用户,就像使用mailto:一样 我读过这篇文章,但有几个问题: 我不想使用mailto,因为官方不支持附件 当使用System.Net.Mail和SMTP类(在接受的答案中提供的代码)时,我不确定如何弹出消息供用户处理,而不仅仅是邮寄消息。不确定这是否可能 此外,当使用上述解决方案时(#2),我不确定如何获取用户的电子邮件服务器 在下面提供的答案中,使用MAPI32.DLL的自定义包装器提供了代码项目解决方案。这里的问题是,本文
mailto:
一样
我读过这篇文章,但有几个问题:
mailto
,因为官方不支持附件那么,这个问题还有其他简单的解决方案吗?是否有另一种简单的方法来弹出默认邮件客户端,其中的附件预先填充了.NET?可能是另一个MAPI包装器,但许可证非常宽松?一个.NET MAPI包装器确实是最好的解决方案-google的“MAPI.NET包装器”返回了许多结果,我相信其中一个将具有合适的许可证:
- -
public class MailMessage
{
#region Constants and Fields
private readonly string _body;
private readonly string _subject;
private readonly List<MapiFileDesc> _attachments;
private readonly List<MapiRecipDesc> _recipients;
#endregion
#region Constructors and Destructors
private MailMessage()
{
}
public MailMessage(
string subject, string body, IEnumerable<MailAttachment> attachments, IEnumerable<MailRecipient> recipients)
{
this._subject = subject;
this._body = body;
this._attachments = new List<MapiFileDesc>();
this._recipients = new List<MapiRecipDesc>();
if (attachments != null)
{
foreach (var attachment in attachments)
{
_attachments.Add(attachment.GetMapiFileDesc());
}
}
if (recipients != null)
{
foreach (var recipient in recipients)
{
_recipients.Add(recipient.GetMapiRecipDesc());
}
}
}
#endregion
#region Public Methods
public void ShowDialog()
{
int result = this.ShowMail();
if (!IsSuccess(result))
{
throw new Exception(GetMapiErrorMessage(result));
}
}
#endregion
#region Methods
private int ShowMail()
{
var message = new MapiMessage();
message.Subject = this._subject;
message.NoteText = this._body;
int attachmentCount;
message.Files = AllocMapiDescArray(_attachments, out attachmentCount);
message.FileCount = attachmentCount;
int recipientCount;
message.Recipients = AllocMapiDescArray(_recipients, out recipientCount);
message.RecipientCount = recipientCount;
int error = Mapi32.MAPISendMail(IntPtr.Zero, IntPtr.Zero, message, Mapi32.MAPI_DIALOG, 0);
DeallocMapiDescArray<MapiFileDesc>(message.Files, message.FileCount);
DeallocMapiDescArray<MapiRecipDesc>(message.Recipients, message.RecipientCount);
return error;
}
private static IntPtr AllocMapiDescArray<T>(ICollection<T> mapiDescCollection, out int mapiDescCount)
{
IntPtr mapiMapiDescArrayPtr = IntPtr.Zero;
mapiDescCount = 0;
if (mapiDescCollection != null && mapiDescCollection.Count > 0)
{
int mapiDescSize = Marshal.SizeOf(typeof(T));
mapiMapiDescArrayPtr = Marshal.AllocHGlobal(mapiDescCollection.Count * mapiDescSize);
var tmp = (int)mapiMapiDescArrayPtr;
foreach (var mapiDesc in mapiDescCollection)
{
Marshal.StructureToPtr(mapiDesc, (IntPtr)tmp, false);
tmp += mapiDescSize;
}
mapiDescCount = mapiDescCollection.Count;
}
return mapiMapiDescArrayPtr;
}
private static void DeallocMapiDescArray<T>(IntPtr mapiDescArrayPtr, int mapiDescArrayCount)
{
if (mapiDescArrayPtr != IntPtr.Zero)
{
int mapiDescSize = Marshal.SizeOf(typeof(T));
var tmp = (int)mapiDescArrayPtr;
for (int i = 0; i < mapiDescArrayCount; i++)
{
Marshal.DestroyStructure((IntPtr)tmp, typeof(T));
tmp += mapiDescSize;
}
Marshal.FreeHGlobal(mapiDescArrayPtr);
}
}
private static bool IsSuccess(int errorCode)
{
return (errorCode == Mapi32.SUCCESS_SUCCESS || errorCode == Mapi32.MAPI_USER_ABORT);
}
private static string GetMapiErrorMessage(int errorCode)
{
// This should be localized
string error = string.Empty;
switch (errorCode)
{
case Mapi32.MAPI_USER_ABORT:
error = "User Aborted.";
break;
case Mapi32.MAPI_E_FAILURE:
error = "MAPI Failure.";
break;
case Mapi32.MAPI_E_LOGIN_FAILURE:
error = "Login Failure.";
break;
case Mapi32.MAPI_E_DISK_FULL:
error = "MAPI Disk full.";
break;
case Mapi32.MAPI_E_INSUFFICIENT_MEMORY:
error = "MAPI Insufficient memory.";
break;
case Mapi32.MAPI_E_BLK_TOO_SMALL:
error = "MAPI Block too small.";
break;
case Mapi32.MAPI_E_TOO_MANY_SESSIONS:
error = "MAPI Too many sessions.";
break;
case Mapi32.MAPI_E_TOO_MANY_FILES:
error = "MAPI too many files.";
break;
case Mapi32.MAPI_E_TOO_MANY_RECIPIENTS:
error = "MAPI too many recipients.";
break;
case Mapi32.MAPI_E_ATTACHMENT_NOT_FOUND:
error = "MAPI Attachment not found.";
break;
case Mapi32.MAPI_E_ATTACHMENT_OPEN_FAILURE:
error = "MAPI Attachment open failure.";
break;
case Mapi32.MAPI_E_ATTACHMENT_WRITE_FAILURE:
error = "MAPI Attachment Write Failure.";
break;
case Mapi32.MAPI_E_UNKNOWN_RECIPIENT:
error = "MAPI Unknown recipient.";
break;
case Mapi32.MAPI_E_BAD_RECIPTYPE:
error = "MAPI Bad recipient type.";
break;
case Mapi32.MAPI_E_NO_MESSAGES:
error = "MAPI No messages.";
break;
case Mapi32.MAPI_E_INVALID_MESSAGE:
error = "MAPI Invalid message.";
break;
case Mapi32.MAPI_E_TEXT_TOO_LARGE:
error = "MAPI Text too large.";
break;
case Mapi32.MAPI_E_INVALID_SESSION:
error = "MAPI Invalid session.";
break;
case Mapi32.MAPI_E_TYPE_NOT_SUPPORTED:
error = "MAPI Type not supported.";
break;
case Mapi32.MAPI_E_AMBIGUOUS_RECIPIENT:
error = "MAPI Ambiguous recipient.";
break;
case Mapi32.MAPI_E_MESSAGE_IN_USE:
error = "MAPI Message in use.";
break;
case Mapi32.MAPI_E_NETWORK_FAILURE:
error = "MAPI Network failure.";
break;
case Mapi32.MAPI_E_INVALID_EDITFIELDS:
error = "MAPI Invalid edit fields.";
break;
case Mapi32.MAPI_E_INVALID_RECIPS:
error = "MAPI Invalid Recipients.";
break;
case Mapi32.MAPI_E_NOT_SUPPORTED:
error = "MAPI Not supported.";
break;
case Mapi32.MAPI_E_NO_LIBRARY:
error = "MAPI No Library.";
break;
case Mapi32.MAPI_E_INVALID_PARAMETER:
error = "MAPI Invalid parameter.";
break;
}
return string.Format("Error sending email. Error: {0} (code = {1}).", error, errorCode);
}
#endregion
}
public class MailAttachment
{
private string _attachmentFilePath;
public MailAttachment(string attachmentFilePath)
{
_attachmentFilePath = attachmentFilePath;
}
public MapiFileDesc GetMapiFileDesc()
{
var mapiFileDesc = new MapiFileDesc();
mapiFileDesc.Position = -1;
mapiFileDesc.Path = _attachmentFilePath;
mapiFileDesc.Name = Path.GetFileName(_attachmentFilePath);
return mapiFileDesc;
}
}
public class MailRecipient
{
#region Constants and Fields
public string _emailAddress;
public string _displayName;
public MailRecipientType _mailRecipientType = MailRecipientType.To;
#endregion
#region Constructors and Destructors
public MailRecipient(string emailAddress, string displayName, MailRecipientType mailRecipientType)
{
this._emailAddress = emailAddress;
this._displayName = displayName;
this._mailRecipientType = mailRecipientType;
}
#endregion
#region Methods
public MapiRecipDesc GetMapiRecipDesc()
{
var recipDesc = new MapiRecipDesc();
if (this._displayName == null)
{
recipDesc.Name = this._emailAddress;
}
else
{
recipDesc.Name = this._displayName;
recipDesc.Address = this._emailAddress;
}
recipDesc.RecipientClass = (int)this._mailRecipientType;
return recipDesc;
}
#endregion
}
public enum MailRecipientType
{
To = 1,
CC = 2,
BCC = 3
} ;
internal class Mapi32
{
#region Constants and Fields
public const int MAPI_DIALOG = 0x8;
public const int MAPI_E_AMBIGUOUS_RECIPIENT = 21;
public const int MAPI_E_ATTACHMENT_NOT_FOUND = 11;
public const int MAPI_E_ATTACHMENT_OPEN_FAILURE = 12;
public const int MAPI_E_ATTACHMENT_WRITE_FAILURE = 13;
public const int MAPI_E_BAD_RECIPTYPE = 15;
public const int MAPI_E_BLK_TOO_SMALL = 6;
public const int MAPI_E_DISK_FULL = 4;
public const int MAPI_E_FAILURE = 2;
public const int MAPI_E_INSUFFICIENT_MEMORY = 5;
public const int MAPI_E_INVALID_EDITFIELDS = 24;
public const int MAPI_E_INVALID_MESSAGE = 17;
public const int MAPI_E_INVALID_PARAMETER = 998;
public const int MAPI_E_INVALID_RECIPS = 25;
public const int MAPI_E_INVALID_SESSION = 19;
public const int MAPI_E_LOGIN_FAILURE = 3;
public const int MAPI_E_MESSAGE_IN_USE = 22;
public const int MAPI_E_NETWORK_FAILURE = 23;
public const int MAPI_E_NOT_SUPPORTED = 26;
public const int MAPI_E_NO_LIBRARY = 999;
public const int MAPI_E_NO_MESSAGES = 16;
public const int MAPI_E_TEXT_TOO_LARGE = 18;
public const int MAPI_E_TOO_MANY_FILES = 9;
public const int MAPI_E_TOO_MANY_RECIPIENTS = 10;
public const int MAPI_E_TOO_MANY_SESSIONS = 8;
public const int MAPI_E_TYPE_NOT_SUPPORTED = 20;
public const int MAPI_E_UNKNOWN_RECIPIENT = 14;
public const int MAPI_LOGON_UI = 0x1;
public const int MAPI_USER_ABORT = 1;
public const int SUCCESS_SUCCESS = 0;
#endregion
#region Public Methods
[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
public static extern int MAPILogon(IntPtr hwnd, string prf, string pw, int flg, int rsv, ref IntPtr sess);
[DllImport("MAPI32.DLL")]
public static extern int MAPISendMail(IntPtr session, IntPtr hwnd, MapiMessage message, int flg, int rsv);
#endregion
}
[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 = IntPtr.Zero;
}
[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 = IntPtr.Zero;
public int RecipientCount;
public IntPtr Recipients = IntPtr.Zero;
public int FileCount;
public IntPtr Files = IntPtr.Zero;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiRecipDesc
{
public int Reserved;
public int RecipientClass;
public string Name;
public string Address;
public int eIDSize;
public IntPtr EntryID = IntPtr.Zero;
}
公共类邮件消息
{
#区域常数和字段
私有只读字符串\u体;
私有只读字符串\u主题;
专用只读列表附件;
私人只读列表\u收件人;
#端区
#区域构造函数和析构函数
私人邮件()
{
}
公开邮件(
字符串主题、字符串正文、IEnumerable附件、IEnumerable收件人)
{
这个._subject=subject;
这个。_body=body;
这是。_attachments=新列表();
这是。_recipients=新列表();
如果(附件!=null)
{
foreach(附件中的var附件)
{
_Add(attachment.GetMapiFileDesc());
}
}
如果(收件人!=null)
{
foreach(收件人中的var收件人)
{
_recipients.Add(recipient.GetMapiRecipDesc());
}
}
}
#端区
#区域公共方法
公共对话框()
{
int result=this.ShowMail();
如果(!IsSuccess(结果))
{
抛出新异常(GetMapErrorMessage(结果));
}
}
#端区
#区域方法
私有int ShowMail()
{
var message=new MapiMessage();
message.Subject=this.\u Subject;
message.NoteText=此。\正文;
int attachmentCount;
message.Files=AllocMapiDescArray(\u附件,out attachmentCount);
message.FileCount=attachmentCount;
整数接受计数;
message.Recipients=AllocMapiDescArray(_Recipients,out recipientCount);
message.RecipientCount=RecipientCount;
int error=Mapi32.MAPISendMail(IntPtr.Zero,IntPtr.Zero,消息,Mapi32.MAPI_对话框,0);
DeallocMapiDescArray(message.Files、message.FileCount);
DealLocalMapiDescArray(message.Recipients,message.RecipientCount);
返回误差;
}
专用静态IntPtr AllocMapiDescArray(ICollection MapidesCollection,out int MapidesCount)
{
IntPtr mapimapidescraryptr=IntPtr.Zero;
mapiDescCount=0;
如果(mapiDescCollection!=null&&mapiDescCollection.Count>0)
{
int-mapiDescSize=Marshal.SizeOf(typeof(T));
mapidescarrayptr=Marshal.AllocHGlobal(mapiDescCollection.Count*mapiDescSize);
var tmp=(int)mapidescarrayptr;
foreach(mapiDescCollection中的var mapiDesc)
{
Marshal.StructureToPtr(mapiDesc,(IntPtr)tmp,false);
tmp+=mapiDescSize;
}
mapiDescCount=mapiDescCollection.Count;
}
返回mapiMapiDescArrayPtr;
}
私有静态void DealLocalMapiDescArray(IntPtr mapiDescArrayPtr、int mapiDescArrayCount)
{
if(mapiDescArrayPtr!=IntPtr.Zero)
{
int-mapiDescSize=Marshal.SizeOf(typeof(T));
var tmp=(int)mapiDescArrayPtr;
对于(int i=0;i