MAPISendMail не работает, когда Outlook работает - PullRequest
1 голос
/ 25 февраля 2009

Я уже некоторое время использую Mapi32 из приложения Winforms для отправки нового почтового сообщения с вложениями, и это работает очень хорошо. (Да, я знаю, что вызов в MAPI32 из C # не поддерживается.)

В течение последних нескольких дней он перестал работать, когда 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;
}

Ответы [ 3 ]

2 голосов
/ 19 июля 2013

Если ваше приложение работает с повышенными привилегиями (то есть с правами администратора), а Outlook - нет, отправка завершится неудачно. Вам нужно будет сказать пользователю, чтобы он закрыл все запущенные экземпляры Outlook и повторил попытку.

1 голос
/ 12 октября 2009

int result = MAPISendMail (сессия, winhandle, msg, MAPI_LOGON_UI | MAPI_DIALOG, 0);

   return result;

Что это возвращает?

0 голосов
/ 25 февраля 2009

Ну, кроме очевидного комментария "использовать поддерживаемые методы отправки почты C #", мне интересно, если что-то случилось с файлом mapi32.dll - вы пробовали "Обнаружить и восстановить" в Outlook?

Я также прочитал здесь (http://office.microsoft.com/en-us/outlook/HP011164781033.aspx)), что вы можете сделать несколько шагов (пост и комментарии), чтобы заставить Outlook восстановить или заменить dll.

...