none
MAPI MAPISendMail e finestra di dialogo conferma invio

    Domanda

  • Salve a tutti,
    Ho la necessità di inviare una serie di mail tramite una applicazione c#,non posso utilizzare  System.Net.Mail, perchè uno dei requisiti dell'applicazione c'è la necessita di lasciarne traccia nel client di posta predefinito che possono essere Outlook Express/Outlook/Windows Live Mail.
    Utilizzando il codice seguente sono riuscito egregiamente a risolvere il problema tranne per il fatto che per ogni invio mi compare una finestra di conferma dell'invio.

    Ho provato ad utilizzare anche la libreria MapiEx ma ha problemi di stabilità.

    Avete qualche suggerimento?
    /******************************************************
                       Simple MAPI.NET
    		      netmaster@swissonline.ch
    *******************************************************/
    
    using System;
    using System.Collections;
    using System.Globalization;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Text;
    
    
    namespace Win32Mapi
    {
    
    
        public class Mapi : IDisposable
        {
    
    
            #region SESSION
            // ----------------------------------------------------------- SESSION ---------
    
            public bool Logon(IntPtr hwnd)
            {
                winhandle = hwnd;
                error = MAPILogon(hwnd, null, null, 0, 0, ref session);
                if (error != 0)
                    error = MAPILogon(hwnd, null, null, MapiLogonUI, 0, ref session);
                return error == 0;
            }
    
            public void Reset()
            {
                findseed = null;
                origin = new MapiRecipDesc();
                recpts.Clear();
                attachs.Clear();
                lastMsg = null;
            }
    
            public void Logoff()
            {
                if (session != IntPtr.Zero)
                {
                    error = MAPILogoff(session, winhandle, 0, 0);
                    session = IntPtr.Zero;
                }
            }
    
    
            [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
            private static extern int MAPILogon(IntPtr hwnd, string prf, string pw,
                                                    int flg, int rsv, ref IntPtr sess);
            [DllImport("MAPI32.DLL")]
            private static extern int MAPILogoff(IntPtr sess, IntPtr hwnd,
                                                    int flg, int rsv);
    
            private const int MapiLogonUI = 0x00000001;
            private const int MapiPasswordUI = 0x00020000;
            private const int MapiNewSession = 0x00000002;
            private const int MapiForceDownload = 0x00001000;
            private const int MapiExtendedUI = 0x00000020;
    
    
            private IntPtr session = IntPtr.Zero;
            private IntPtr winhandle = IntPtr.Zero;
            #endregion
    
    
    
            #region SENDING
            // ----------------------------------------------------------- SENDING ---------
    
            public bool Send(string sub, string txt)
            {
                lastMsg = new MapiMessage();
                lastMsg.subject = sub;
                lastMsg.noteText = txt;
    
                // set pointers
                lastMsg.originator = AllocOrigin();
                lastMsg.recips = AllocRecips(out lastMsg.recipCount);
                lastMsg.files = AllocAttachs(out lastMsg.fileCount);
    
                error = MAPISendMail(session, winhandle, lastMsg, 0, 0);
                Dealloc();
                Reset();
                return error == 0;
            }
    
            public void AddRecip(string name, string addr, bool cc)
            {
                MapiRecipDesc dest = new MapiRecipDesc();
                if (cc)
                    dest.recipClass = MapiCC;
                else
                    dest.recipClass = MapiTO;
                dest.name = name;
                dest.address = addr;
                recpts.Add(dest);
            }
    
            public void SetSender(string sname, string saddr)
            {
                origin.name = sname;
                origin.address = saddr;
            }
    
            public void Attach(string filepath)
            {
                attachs.Add(filepath);
            }
    
            private IntPtr AllocOrigin()
            {
                origin.recipClass = MapiORIG;
                Type rtype = typeof(MapiRecipDesc);
                int rsize = Marshal.SizeOf(rtype);
                IntPtr ptro = Marshal.AllocHGlobal(rsize);
                Marshal.StructureToPtr(origin, ptro, false);
                return ptro;
            }
    
            private IntPtr AllocRecips(out int recipCount)
            {
                recipCount = 0;
                if (recpts.Count == 0)
                    return IntPtr.Zero;
    
                Type rtype = typeof(MapiRecipDesc);
                int rsize = Marshal.SizeOf(rtype);
                IntPtr ptrr = Marshal.AllocHGlobal(recpts.Count * rsize);
    
                int runptr = (int)ptrr;
                for (int i = 0; i < recpts.Count; i++)
                {
                    Marshal.StructureToPtr(recpts[i] as MapiRecipDesc, (IntPtr)runptr, false);
                    runptr += rsize;
                }
    
                recipCount = recpts.Count;
                return ptrr;
            }
    
            private IntPtr AllocAttachs(out int fileCount)
            {
                fileCount = 0;
                if (attachs == null)
                    return IntPtr.Zero;
                if ((attachs.Count <= 0) || (attachs.Count > 100))
                    return IntPtr.Zero;
    
                Type atype = typeof(MapiFileDesc);
                int asize = Marshal.SizeOf(atype);
                IntPtr ptra = Marshal.AllocHGlobal(attachs.Count * asize);
    
                MapiFileDesc mfd = new MapiFileDesc();
                mfd.position = -1;
                int runptr = (int)ptra;
                for (int i = 0; i < attachs.Count; i++)
                {
                    string path = attachs[i] as string;
                    mfd.name = Path.GetFileName(path);
                    mfd.path = path;
                    Marshal.StructureToPtr(mfd, (IntPtr)runptr, false);
                    runptr += asize;
                }
    
                fileCount = attachs.Count;
                return ptra;
            }
    
            private void Dealloc()
            {
                Type rtype = typeof(MapiRecipDesc);
                int rsize = Marshal.SizeOf(rtype);
    
                if (lastMsg.originator != IntPtr.Zero)
                {
                    Marshal.DestroyStructure(lastMsg.originator, rtype);
                    Marshal.FreeHGlobal(lastMsg.originator);
                }
    
                if (lastMsg.recips != IntPtr.Zero)
                {
                    int runptr = (int)lastMsg.recips;
                    for (int i = 0; i < lastMsg.recipCount; i++)
                    {
                        Marshal.DestroyStructure((IntPtr)runptr, rtype);
                        runptr += rsize;
                    }
                    Marshal.FreeHGlobal(lastMsg.recips);
                }
    
                if (lastMsg.files != IntPtr.Zero)
                {
                    Type ftype = typeof(MapiFileDesc);
                    int fsize = Marshal.SizeOf(ftype);
    
                    int runptr = (int)lastMsg.files;
                    for (int i = 0; i < lastMsg.fileCount; i++)
                    {
                        Marshal.DestroyStructure((IntPtr)runptr, ftype);
                        runptr += fsize;
                    }
                    Marshal.FreeHGlobal(lastMsg.files);
                }
            }
    
            private const int MapiORIG = 0;
            private const int MapiTO = 1;
            private const int MapiCC = 2;
            private const int MapiBCC = 3;
    
            [DllImport("MAPI32.DLL")]
            private static extern int MAPISendMail(IntPtr sess, IntPtr hwnd,
                                                    MapiMessage message,
                                                    int flg, int rsv);
    
            private MapiRecipDesc origin = new MapiRecipDesc();
            private ArrayList recpts = new ArrayList();
            private ArrayList attachs = new ArrayList();
            #endregion
    
    
    
            #region FINDING
            // ----------------------------------------------------------- FINDING ---------
    
            public bool Next(ref MailEnvelop env)
            {
                error = MAPIFindNext(session, winhandle, null, findseed,
                                        MapiLongMsgID, 0, lastMsgID);
                if (error != 0)
                    return false;
                findseed = lastMsgID.ToString();
    
                IntPtr ptrmsg = IntPtr.Zero;
                error = MAPIReadMail(session, winhandle, findseed,
                                    MapiEnvOnly | MapiPeek | MapiSuprAttach, 0, ref ptrmsg);
                if ((error != 0) || (ptrmsg == IntPtr.Zero))
                    return false;
    
                lastMsg = new MapiMessage();
                Marshal.PtrToStructure(ptrmsg, lastMsg);
                MapiRecipDesc orig = new MapiRecipDesc();
                if (lastMsg.originator != IntPtr.Zero)
                    Marshal.PtrToStructure(lastMsg.originator, orig);
    
                env.id = findseed;
                env.date = DateTime.ParseExact(lastMsg.dateReceived, "yyyy/MM/dd HH:mm", DateTimeFormatInfo.InvariantInfo);
                env.subject = lastMsg.subject;
                env.from = orig.name;
                env.unread = (lastMsg.flags & MapiUnread) != 0;
                env.atts = lastMsg.fileCount;
    
                error = MAPIFreeBuffer(ptrmsg);
                return error == 0;
            }
    
    
            [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
            private static extern int MAPIFindNext(IntPtr sess, IntPtr hwnd, string typ,
                                                    string seed, int flg, int rsv, StringBuilder id);
    
            private const int MapiUnreadOnly = 0x00000020;
            private const int MapiGuaranteeFiFo = 0x00000100;
            private const int MapiLongMsgID = 0x00004000;
    
            private StringBuilder lastMsgID = new StringBuilder(600);
            private string findseed = null;
            #endregion
    
    
    
    
            #region READING
            // ----------------------------------------------------------- READING ---------
    
            public string Read(string id, out MailAttach[] aat)
            {
                aat = null;
                IntPtr ptrmsg = IntPtr.Zero;
                error = MAPIReadMail(session, winhandle, id,
                                        MapiPeek | MapiSuprAttach, 0, ref ptrmsg);
                if ((error != 0) || (ptrmsg == IntPtr.Zero))
                    return null;
    
                lastMsg = new MapiMessage();
                Marshal.PtrToStructure(ptrmsg, lastMsg);
    
                if ((lastMsg.fileCount > 0) && (lastMsg.fileCount < 100) && (lastMsg.files != IntPtr.Zero))
                    GetAttachNames(out aat);
    
                MAPIFreeBuffer(ptrmsg);
                return lastMsg.noteText;
            }
    
            public bool Delete(string id)
            {
                error = MAPIDeleteMail(session, winhandle, id, 0, 0);
                return error == 0;
            }
    
            public bool SaveAttachm(string id, string name, string savepath)
            {
                IntPtr ptrmsg = IntPtr.Zero;
                error = MAPIReadMail(session, winhandle, id,
                                        MapiPeek, 0, ref ptrmsg);
                if ((error != 0) || (ptrmsg == IntPtr.Zero))
                    return false;
    
                lastMsg = new MapiMessage();
                Marshal.PtrToStructure(ptrmsg, lastMsg);
                bool f = false;
                if ((lastMsg.fileCount > 0) && (lastMsg.fileCount < 100) && (lastMsg.files != IntPtr.Zero))
                    f = SaveAttachByName(name, savepath);
                MAPIFreeBuffer(ptrmsg);
                return f;
            }
    
    
            private void GetAttachNames(out MailAttach[] aat)
            {
                aat = new MailAttach[lastMsg.fileCount];
                Type fdtype = typeof(MapiFileDesc);
                int fdsize = Marshal.SizeOf(fdtype);
                MapiFileDesc fdtmp = new MapiFileDesc();
                int runptr = (int)lastMsg.files;
                for (int i = 0; i < lastMsg.fileCount; i++)
                {
                    Marshal.PtrToStructure((IntPtr)runptr, fdtmp);
                    runptr += fdsize;
                    aat[i] = new MailAttach();
                    if (fdtmp.flags == 0)
                    {
                        aat[i].position = fdtmp.position;
                        aat[i].name = fdtmp.name;
                        aat[i].path = fdtmp.path;
                    }
                }
            }
    
    
            private bool SaveAttachByName(string name, string savepath)
            {
                bool f = true;
                Type fdtype = typeof(MapiFileDesc);
                int fdsize = Marshal.SizeOf(fdtype);
                MapiFileDesc fdtmp = new MapiFileDesc();
                int runptr = (int)lastMsg.files;
                for (int i = 0; i < lastMsg.fileCount; i++)
                {
                    Marshal.PtrToStructure((IntPtr)runptr, fdtmp);
                    runptr += fdsize;
                    if (fdtmp.flags != 0)
                        continue;
                    if (fdtmp.name == null)
                        continue;
    
                    try
                    {
                        if (name == fdtmp.name)
                        {
                            if (File.Exists(savepath))
                                File.Delete(savepath);
                            File.Move(fdtmp.path, savepath);
                        }
                    }
                    catch (Exception)
                    { f = false; error = 13; }
    
                    try
                    {
                        File.Delete(fdtmp.path);
                    }
                    catch (Exception)
                    { }
                }
                return f;
            }
    
    
            [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
            private static extern int MAPIReadMail(IntPtr sess, IntPtr hwnd, string id,
                                                    int flg, int rsv, ref IntPtr ptrmsg);
    
            [DllImport("MAPI32.DLL")]
            private static extern int MAPIFreeBuffer(IntPtr ptr);
    
            [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
            private static extern int MAPIDeleteMail(IntPtr sess, IntPtr hwnd, string id,
                                                    int flg, int rsv);
    
            private const int MapiPeek = 0x00000080;
            private const int MapiSuprAttach = 0x00000800;
            private const int MapiEnvOnly = 0x00000040;
            private const int MapiBodyAsFile = 0x00000200;
    
            private const int MapiUnread = 0x00000001;
            private const int MapiReceiptReq = 0x00000002;
            private const int MapiSent = 0x00000004;
    
            private MapiMessage lastMsg = null;
            #endregion
    
    
    
    
            #region ADDRESS
    
            public bool SingleAddress(string label, out string name, out string addr)
            {
                name = null;
                addr = null;
                int newrec = 0;
                IntPtr ptrnew = IntPtr.Zero;
                error = MAPIAddress(session, winhandle, null, 1, label, 0, IntPtr.Zero,
                                        0, 0, ref newrec, ref ptrnew);
                if ((error != 0) || (newrec < 1) || (ptrnew == IntPtr.Zero))
                    return false;
    
                MapiRecipDesc recip = new MapiRecipDesc();
                Marshal.PtrToStructure(ptrnew, recip);
                name = recip.name;
                addr = recip.address;
    
                MAPIFreeBuffer(ptrnew);
                return true;
            }
    
    
            [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
            private static extern int MAPIAddress(IntPtr sess, IntPtr hwnd, string caption,
                                                    int editfld, string labels, int recipcount, IntPtr ptrrecips,
                                                    int flg, int rsv, ref int newrec, ref IntPtr ptrnew);
            #endregion
    
    
    
    
            #region ERRORS
            // ----------------------------------------------------------- ERRORS ---------
    
            public string Error()
            {
                if (error > 0 && error <= 26)
                    return errors[error];
                return "?unknown? [" + error.ToString() + "]";
            }
    
            private int error = 0;
    
            private readonly string[] errors = new string[] {
    		"OK [0]", "User abort [1]", "General MAPI failure [2]", "MAPI login failure [3]",
    		"Disk full [4]", "Insufficient memory [5]", "Access denied [6]", "-unknown- [7]",
    		"Too many sessions [8]", "Too many files were specified [9]", "Too many recipients were specified [10]", "A specified attachment was not found [11]",
    		"Attachment open failure [12]", "Attachment write failure [13]", "Unknown recipient [14]", "Bad recipient type [15]",
    		"No messages [16]", "Invalid message [17]", "Text too large [18]", "Invalid session [19]",
    		"Type not supported [20]", "A recipient was specified ambiguously [21]", "Message in use [22]", "Network failure [23]",
    		"Invalid edit fields [24]", "Invalid recipients [25]", "Not supported [26]" 
    		};
            #endregion
    
    
            #region IDisposable Members
    
            public void Dispose()
            {
                Dispose(true);
            }
    
            private void Dispose(bool dispose)
            {
                Logoff();
                if (dispose)
                    GC.SuppressFinalize(this);
            }
    
            ~Mapi()
            {
                Dispose(false);
            }
    
            #endregion
        }
    
    
    
    
    
    
    
    
        // ********************************************* MAPI STRUCTURES *********************************************
    
        [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;		// MapiRecipDesc* [1]
            public int recipCount;
            public IntPtr recips;			// MapiRecipDesc* [n]
            public int fileCount;
            public IntPtr files;			// MapiFileDesc*  [n]
        }
    
        [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;			// void*
        }
    
        [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;
        }
    
    
    
    
    
        // ********************************************* HELPER STRUCTURES *********************************************
    
        public class MailEnvelop
        {
            public string id;
            public DateTime date;
            public string from;
            public string subject;
            public bool unread;
            public int atts;
        }
    
        public class MailAttach
        {
            public int position;
            public string path;
            public string name;
        }
    
    }
    

    martedì 16 marzo 2010 14:53

Risposte

  • Non hai mezzo di bypassare da codice, se non con hack sporchissimi
    forse, quella dialog, fortunatamente aggiungo io :-)

    ..m

    --
    Mauro Servienti
    {C67C0157-5D98-4733-A75E-93CAEE4BADC8}
    Microsoft MVP - Visual C# / MCP
    http://mvp.support.microsoft.com
    http://blogs.ugidotnet.org/topics
    whynot [ at ] topics [ dot ] it



    Mauro Servienti
    {C67C0157-5D98-4733-A75E-93CAEE4BADC8}
    Microsoft MVP - Visual C# / MCP
    http://mvp.support.microsoft.com
    http://blogs.ugidotnet.org/topics
    whynot [ at ] topics [ dot ] it
    giovedì 18 marzo 2010 07:18

Tutte le risposte

  • Non hai mezzo di bypassare da codice, se non con hack sporchissimi
    forse, quella dialog, fortunatamente aggiungo io :-)

    ..m

    --
    Mauro Servienti
    {C67C0157-5D98-4733-A75E-93CAEE4BADC8}
    Microsoft MVP - Visual C# / MCP
    http://mvp.support.microsoft.com
    http://blogs.ugidotnet.org/topics
    whynot [ at ] topics [ dot ] it



    Mauro Servienti
    {C67C0157-5D98-4733-A75E-93CAEE4BADC8}
    Microsoft MVP - Visual C# / MCP
    http://mvp.support.microsoft.com
    http://blogs.ugidotnet.org/topics
    whynot [ at ] topics [ dot ] it
    giovedì 18 marzo 2010 07:18
  • Grazie mauro per la risposta.
    comunque oggi o trovato una soluzione parziale.

    Per outlook express/Windows Mail e sufficiente cambiare le impostazioni di protezione in Strumenti -> Opzioni -> Protezione e togliere la spunta su "Avvisa se altre applicazioni tentano l'invio di posta con l'account in uso"

    Per Outlook 2003 e successivi non ho trovato ancora niente in riguardo,anche se qui viene detto che è possibile farlo tramite policy, ma scaricando gli adm non sono riuscito a trovare riferimenti a tale policy.

    Avevo pensato pure io agli hack ma non mi piace come soluzione.



    giovedì 18 marzo 2010 09:58