2009-02-25 6 views
1

J'ai utilisé Mapi32 à partir d'une application Winforms pour envoyer un nouveau message avec des pièces jointes depuis un moment maintenant, et cela a très bien fonctionné. (Oui, je suis conscient que l'appel dans MAPI32 à partir de C# n'est pas pris en charge.)MAPISendMail ne fonctionne pas lorsque Outlook est en cours d'exécution

Au cours des derniers jours, il a cessé de fonctionner lorsque Outlook est en cours d'exécution. Toutefois, si Outlook n'est pas en cours d'exécution, il fonctionnera comme prévu. Cela se produit à la fois dans Vista et XP.

Est-ce que des clients ont eu ce problème? Comment as-tu résolu ça?

Voici le code que je l'ai utilisé:

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; 
} 
+1

Le niveau d'intégrité du processus appelant est probablement différent du niveau d'intégrité d'Outlook. Utilisez Process Explorer pour trouver les IL des processus en cours d'exécution. – wqw

+0

peut ne pas être lié à votre problème, mais j'avais MAPISendMail suspendus avec Outlook parce que les adresses de courrier avaient des espaces de fin! –

Répondre

0

Eh bien, autre que la « utilisation pris en charge C# par correspondance envoyer des méthodes » évidentes commentaire, je me demande si quelque chose est arrivé au fichier mapi32.dll - ont vous avez essayé "Détecter et réparer" dans Outlook?

Je lis aussi ici (http://office.microsoft.com/en-us/outlook/HP011164781033.aspx) qu'il y a quelques étapes que vous pouvez faire (la publication et les commentaires) pour qu'Outlook répare ou remplace la DLL.

1

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

return result; 

Que faut-il revenir?

+0

J'ai également testé la manière d'envoyer des emails. Mes tests n'envoient pas d'e-mail, la méthode MAPISendMail renvoie 2. – constructor

+0

Cela fait un bon moment que je travaillais dans MAPI. Toutefois, vérifiez que vous avez configuré un client de messagerie à utiliser avec MAPI, car cette valeur n'est pas définie par défaut. Voir https://msdn.microsoft.com/fr-fr/library/windows/desktop/ee909492%28v=vs.85%29.aspx –

2

Si votre application fonctionne avec des privilèges élevés (c'est-à-dire en tant qu'administrateur) et que Outlook ne l'est pas, l'envoi échouera. Vous devrez indiquer à l'utilisateur de fermer toutes les instances en cours d'exécution d'Outlook et réessayer.

Questions connexes