Outlook 运行时 MAPISendMail 不起作用

发布于 07-14 16:30 字数 3014 浏览 8 评论 0原文

我已经使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

╰ゝ天使的微笑2024-07-21 16:30:29

如果您的应用程序以提升权限(即以管理员身份)运行,而 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.

扎心2024-07-21 16:30:29

int 结果 = MAPISendMail(session, winhandle, msg, MAPI_LOGON_UI | MAPI_DIALOG, 0);

 返回结果; 
  

它返回什么?

int result = MAPISendMail(session, winhandle, msg, MAPI_LOGON_UI | MAPI_DIALOG, 0);

   return result;

What does it return?

一紙繁鸢2024-07-21 16:30:29

好吧,除了明显的“使用支持的 C# 邮件发送方法”评论之外,我想知道 mapi32.dll 文件是否发生了问题 - 您是否尝试过 Outlook 中的“检测和修复”?

我还在这里阅读(http://office.microsoft.com/en-us /outlook/HP011164781033.aspx),您可以执行一些步骤(帖子和评论)来让 Outlook 修复或替换 dll。

Well, other than the obvious "use supported C# mail-sending methods" comment, I wonder if something happened to the mapi32.dll file - have you tried a "Detect and Repair" in Outlook?

I also read here (http://office.microsoft.com/en-us/outlook/HP011164781033.aspx) that there are some steps you can do (the post and the comments) to get Outlook to repair or replace the dll.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文