俄文邮件内容显示为问号:求支持附件与多语言的邮件弹窗方案
可行解决方案
我帮你整理了几个能解决问题的方案,既满足加附件、弹出邮件编辑对话框的需求,又能保证俄文等非英文文本正常显示:
方案1:升级现有MAPI实现为Unicode版本
你目前用的CodeProject上的MAPI实现,大概率是基于ANSI编码的MAPISendMailA函数——这就是俄文变成问号的核心原因,ANSI编码不支持Unicode字符集。只要把它改成Unicode版本的MAPISendMailW,就能彻底解决编码问题,同时保留附件支持和调用默认邮件客户端的能力。
具体修改要点:
- 在P/Invoke声明里,替换函数为
MAPISendMailW并指定Unicode字符集:
[DllImport("mapi32.dll", CharSet = CharSet.Unicode)] private static extern uint MAPISendMail(IntPtr sess, IntPtr hwnd, MapiMessage message, int flg, int rsv);
- 确保
MapiMessage结构体里的字符串字段(比如主题、正文)都标记为宽字符类型:
public struct MapiMessage { public int ulReserved; [MarshalAs(UnmanagedType.LPWStr)] public string lpszSubject; [MarshalAs(UnmanagedType.LPWStr)] public string lpszNoteText; // 其他字段保持原有定义即可 }
修改后,俄文等Unicode文本就能正常显示,不会被替换成问号,同时依然支持添加附件、弹出编辑对话框,且能调用系统默认邮件客户端。
方案2:使用Windows Runtime的EmailMessage API(Windows 10+)
如果你的应用主要面向Windows 10及以上系统,可以直接用Windows原生的EmailMessage类。这个API天生支持Unicode,添加附件的逻辑更简洁,还会自动唤起默认邮件客户端的编辑窗口。
示例代码如下:
using Windows.ApplicationModel.Email; using System.Threading.Tasks; public async Task ComposeEmailWithAttachment(string ccEmailId, string subject, string body, string attachmentPath) { var email = new EmailMessage(); // 添加抄送收件人 email.Cc.Add(new EmailRecipient(ccEmailId)); // 直接传入俄文主题和正文,原生支持Unicode email.Subject = subject; email.Body = body; // 添加本地附件 var attachment = new EmailAttachment(attachmentPath); email.Attachments.Add(attachment); // 弹出邮件编辑窗口 await EmailManager.ShowComposeNewEmailAsync(email); }
注意:这个方法要求项目目标框架为.NET Core 3.0+、.NET 5+或UWP,且运行在Windows 10 1607版本及以上。
方案对比
- 升级MAPI:兼容性拉满,支持全版本Windows系统和主流邮件客户端(Outlook、Thunderbird等),是最稳妥的选择。
- Windows Runtime API:代码更简洁直观,但仅适配较新的Windows平台,适合面向现代Windows环境的应用。
内容的提问来源于stack exchange,提问作者Sumit Pannu
相关产品推荐
相关产品推荐

