C# Winforms 无异常从外部函数崩溃,退出代码为 40445582 (0x269268e)
Posted
技术标签:
【中文标题】C# Winforms 无异常从外部函数崩溃,退出代码为 40445582 (0x269268e)【英文标题】:C# Winforms Crashing from external function without exception, with exit code 40445582 (0x269268e) 【发布时间】:2020-09-15 20:29:12 【问题描述】:正如标题所示,我有一个用 C# .Net Framework 4.8 编写的 Winform;它从 mapi32.dll 调用 MAPISendMail 外部函数,在 Outlook 中为用户打开一个新的消息窗口,最初填充了收件人地址和消息(有时还有附件):
[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)”。我已经用谷歌搜索了试图找到这段代码的含义,但一无所获。有没有人对这里可能发生的事情有任何见解,甚至可能有一种方法可以让我捕捉到这个错误以防止表单关闭?
【问题讨论】:
阅读以下页面:pinvoke.net/default.aspx/mapi32.MAPISendMail Don't do it. @CHowell 不幸的是,似乎没有任何方法可以处理附件,因为它被认为存在安全风险。 MAPI 是一个已弃用的 API,您应该尽可能避免使用它,因为它可能会在将来的某个时候完全消失。我很欣赏如果您的用户习惯了此功能,这对他们来说不太可能有问题,但是让他们知道您正在删除该功能,然后将其删除,这比等待 Microsoft 删除它然后再删除它是一个更好的解决方案惊慌失措。 使用 Outlook 互操作的最大问题是它可能无法与 Outlook 以外的任何电子邮件客户端一起使用,而 MAPI 可以与任何系统默认电子邮件客户端一起使用(与 MAPI 一样) .如果您只关心 Outlook,那么 interop 绝对是最佳选择 - 只需确保使用官方 NuGet 包 (nuget.org/packages/Microsoft.Office.Interop.Outlook) 而不是尝试将您的应用程序硬链接到 interop DLL。 API 肯定没有太大变化,所以你找到的答案应该还是不错的。 在这种情况下,我很幸运我知道我的所有用户都在使用 Outlook!感谢您的帮助。如果我的声望 +15,我会支持你和 @HansPassant。 【参考方案1】:我基本上问错了问题。感谢 Hans Passant 和 Ian Kemp 指出 MAPI is long deprecated and should be avoided。
感谢this SO question,我使用了Microsoft.Office.Interop.Outlook,并制作了一个非常简单的包装类:
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。
【讨论】:
以上是关于C# Winforms 无异常从外部函数崩溃,退出代码为 40445582 (0x269268e)的主要内容,如果未能解决你的问题,请参考以下文章
程序崩溃优雅退出之-SetUnhandledExceptionFilter
程序崩溃优雅退出之-SetUnhandledExceptionFilter