C#Winforms从外部函数崩溃,无一例外,退出代码404455820x269268e

问题描述

正如标题所示,我有一个用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。