问题描述
正如标题所示,我有一个用C#.Net Framework 4.8编写的Winform;它从mapi32.dll调用MAPISendMail外部函数,以在Outlook中为用户打开一个新的消息窗口,该窗口最初填充了to地址和消息(有时是附件):
[DllImport("MAPI32.DLL")]
public static extern int MAPISendMail(IntPtr session,IntPtr hwnd,MapiMessage message,int flg,int rsv);
注意:如果您知道有什么可以代替MAPI来描述的用法,那就太了不起了。
无论出于何种原因,都会不时地导致整个winform挂起一会儿,然后关闭。除了上述悬挂之外,没有迹象表明会发生这种情况,据我所知,没有任何规律可言。我可以去几个小时,却从未遇到过。
此外,发生这种情况时,不会捕获任何try / catch块。我当然尝试捕获标准Exception
,但是也尝试捕获RuntimeWrappedException
,但也不会被触发:
try
{
error = MAPIHelperInterop.MAPISendMail(IntPtr.Zero,IntPtr.Zero,message,MAPI_DIALOG,0);
}
catch (RuntimeWrappedException rwe)
{
throw rwe.InnerException;
}
catch (Exception e)
{
throw e;
}
唯一的错误提示是Debug输出的最后一行,指出“ 程序'PROGRAMNAME'已退出,代码40445582(0x269268e)”。我已尝试搜索该代码的含义,却一无所获。有没有人对这里可能发生的事情有任何见解,也许甚至是我可以捕获此错误以防止表单关闭的方式?
解决方法
我本质上是在问一个错误的问题。感谢Hans Passant和Ian Kemp指出MAPI is long deprecated and should be avoided。
我用Microsoft.Office.Interop.Outlook来代替this SO question,并做了一个非常简单的包装器类:
public class OutlookEmail
{
public OutlookEmail() { }
public OutlookEmail(params string[] toAddrs)
{
To.AddRange(toAddrs);
}
private Application OApp = new Application();
public List<string> To { get; set; } = new List<string>();
public string Subject { get; set; }
public string Body { get; set; }
public List<string> Attachments { get; set; } = new List<string>();
public void ShowDialog()
{
_MailItem oMailItem = (_MailItem)OApp.CreateItem(OlItemType.olMailItem);
oMailItem.To = string.Join("; ",To);
// body,bcc etc...
oMailItem.Subject = Subject;
oMailItem.Body = Body;
if(Attachments != null)
{
foreach (string path in Attachments)
{
oMailItem.Attachments.Add(path);
}
}
oMailItem.Display(true);
}
}
注意::这仅适用于Outlook;对我来说幸运的是,我所有的用户肯定都使用Outlook。