Outlook 运行时 MAPISendMail 不起作用
我已经使用 Winforms 应用程序中的 Mapi32 来发送带附件的新邮件消息有一段时间了,而且效果非常好。 (是的,我知道不支持从 C# 调用 MAPI32。)
在过去几天内,它在 Outlook 运行时停止工作。 但是,如果 Outlook 未运行,它将按预期工作。 Vista 和 XP 中都会发生这种情况。
有SOer遇到过这个问题吗? 你是怎么解决的?
这是我一直在使用的代码:
public class EmailController
{
[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
public static extern int MAPISendMail(IntPtr lhSession, IntPtr ulUIParam,
MapiMessage lpMessage, int flFlags, int ulReserved);
public const int MAPI_LOGON_UI = 0x00000001;
private const int MAPI_DIALOG = 0x00000008;
public static int SendMail(string strAttachmentFileName, string strSubject,string to)
{
IntPtr session = new IntPtr(0);
IntPtr winhandle = new IntPtr(0);
MapiMessage msg = new MapiMessage();
msg.subject = strSubject;
int sizeofMapiDesc = Marshal.SizeOf(typeof(MapiFileDesc));
IntPtr pMapiDesc = Marshal.AllocHGlobal(sizeofMapiDesc);
MapiFileDesc fileDesc = new MapiFileDesc();
fileDesc.position = -1;
int ptr = (int)pMapiDesc;
string path = strAttachmentFileName;
fileDesc.name = Path.GetFileName(path);
fileDesc.path = path;
Marshal.StructureToPtr(fileDesc, (IntPtr)ptr, false);
msg.files = pMapiDesc;
msg.fileCount = 1;
List<MapiRecipDesc> recipsList = new List<MapiRecipDesc>();
MapiRecipDesc recipient = new MapiRecipDesc();
recipient.recipClass = 1;
recipient.name = to;
recipsList.Add(recipient);
int size = Marshal.SizeOf(typeof(MapiRecipDesc));
IntPtr intPtr = Marshal.AllocHGlobal(recipsList.Count * size);
int recipPtr = (int)intPtr;
foreach (MapiRecipDesc mapiDesc in recipsList)
{
Marshal.StructureToPtr(mapiDesc, (IntPtr)recipPtr, false);
recipPtr += size;
}
msg.recips = intPtr;
msg.recipCount = 1;
int result = MAPISendMail(session, winhandle, msg, MAPI_LOGON_UI | MAPI_DIALOG, 0);
return result;
}
}
[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;
public int recipCount;
public IntPtr recips;
public int fileCount;
public IntPtr files;
}
[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;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiRecipDesc
{
public int reserved;
public int recipClass;
public string name;
public string address;
public int eIDSize;
public IntPtr entryID;
}
I've been using Mapi32 from a Winforms app to send bring up a new mail message with attachments for a while now, and it's worked really well. (Yes, I'm aware that calling into MAPI32 from C# is not supported.)
Within the last few days, it has stopped working when Outlook is running. However, if Outlook is not running, it will work as expected. This happens in both Vista and XP.
Have any SOer's had this problem? How did you resolve it?
Here's the code I've been using:
public class EmailController
{
[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
public static extern int MAPISendMail(IntPtr lhSession, IntPtr ulUIParam,
MapiMessage lpMessage, int flFlags, int ulReserved);
public const int MAPI_LOGON_UI = 0x00000001;
private const int MAPI_DIALOG = 0x00000008;
public static int SendMail(string strAttachmentFileName, string strSubject,string to)
{
IntPtr session = new IntPtr(0);
IntPtr winhandle = new IntPtr(0);
MapiMessage msg = new MapiMessage();
msg.subject = strSubject;
int sizeofMapiDesc = Marshal.SizeOf(typeof(MapiFileDesc));
IntPtr pMapiDesc = Marshal.AllocHGlobal(sizeofMapiDesc);
MapiFileDesc fileDesc = new MapiFileDesc();
fileDesc.position = -1;
int ptr = (int)pMapiDesc;
string path = strAttachmentFileName;
fileDesc.name = Path.GetFileName(path);
fileDesc.path = path;
Marshal.StructureToPtr(fileDesc, (IntPtr)ptr, false);
msg.files = pMapiDesc;
msg.fileCount = 1;
List<MapiRecipDesc> recipsList = new List<MapiRecipDesc>();
MapiRecipDesc recipient = new MapiRecipDesc();
recipient.recipClass = 1;
recipient.name = to;
recipsList.Add(recipient);
int size = Marshal.SizeOf(typeof(MapiRecipDesc));
IntPtr intPtr = Marshal.AllocHGlobal(recipsList.Count * size);
int recipPtr = (int)intPtr;
foreach (MapiRecipDesc mapiDesc in recipsList)
{
Marshal.StructureToPtr(mapiDesc, (IntPtr)recipPtr, false);
recipPtr += size;
}
msg.recips = intPtr;
msg.recipCount = 1;
int result = MAPISendMail(session, winhandle, msg, MAPI_LOGON_UI | MAPI_DIALOG, 0);
return result;
}
}
[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;
public int recipCount;
public IntPtr recips;
public int fileCount;
public IntPtr files;
}
[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;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiRecipDesc
{
public int reserved;
public int recipClass;
public string name;
public string address;
public int eIDSize;
public IntPtr entryID;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(3)
好吧,除了明显的“使用支持的 C# 邮件发送方法”评论之外,我想知道 mapi32.dll 文件是否发生了问题 - 您是否尝试过 Outlook 中的“检测和修复”?
我还在这里阅读(http://office.microsoft.com/en-us /outlook/HP011164781033.aspx),您可以执行一些步骤(帖子和评论)来让 Outlook 修复或替换 dll。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
如果您的应用程序以提升权限(即以管理员身份)运行,而 Outlook 不是以提升权限运行,则发送将会失败。 您必须告诉用户关闭所有正在运行的 Outlook 实例,然后重试。
If you're application is running with Elevated Privileges (i.e. as Administrator) and Outlook isn't, the send will fail. You will have to tell the user to close all running instances of Outlook and try again.