/// <summary> /// Allows the user to select recipients from the Simple MAPI address book.</summary> /// <returns> /// An <see cref="Array"/> of <see cref="MapiAddress"/> instances holding the selected /// address book names and the corresponding e-mail addresses.</returns> /// <exception cref="MapiException"> /// <see cref="Mapi.MAPIAddress"/> indicated an error.</exception> /// <remarks><para> /// <b>Address</b> shows a dialog allowing the user to select e-mail recipients from an /// address book, using the Win32 API call <see cref="Mapi.MAPIAddress"/> which is part of /// the Simple MAPI protocol. Only the "To" recipient type is available. /// </para><para> /// <b>Address</b> returns an empty array if the user cancelled the dialog or did not select /// any recipients. No <see cref="MapiException"/> is generated in this case. /// </para><note type="caution"> /// <para>Non-Microsoft e-mail clients rarely support <b>MAPIAddress</b>. Some might report /// an error while others might show a nonfunctional dialog or return invalid data. There is /// no workaround other than using a Microsoft program as the default e-mail client. /// </para><para> /// Also note that Simple MAPI does not specify the order in which <b>MAPIAddress</b> /// returns the selected recipients. <b>Address</b> maintains the selection order for /// Outlook Express, but the order may be reversed or completely arbitrary for other e-mail /// clients.</para></note></remarks> public static MapiAddress[] Address() { // remember current working directory string currentDir = Directory.GetCurrentDirectory(); // prepare recipient list data uint nNewRecips = 0; SafeMapiHandle lpNewRecips = null; try { // invoke MAPIAddress to create a recipient list MapiFlags flags = MapiFlags.MAPI_LOGON_UI; MapiError code = Mapi.MAPIAddress(UIntPtr.Zero, UIntPtr.Zero, null, 1, null, 0, IntPtr.Zero, flags, 0, out nNewRecips, out lpNewRecips); // check for user cancellation if (code == MapiError.MAPI_E_USER_ABORT) { return(new MapiAddress[0]); } // check for null recipient list (buggy MAPI server) if (code == MapiError.SUCCESS_SUCCESS && nNewRecips > 0 && (lpNewRecips == null || lpNewRecips.IsInvalid)) { code = MapiError.MAPI_E_FAILURE; } // throw exception if MAPI reports failure if (code != MapiError.SUCCESS_SUCCESS) { ThrowMapiException(code); } // create (possibly empty) output recipient array MapiAddress[] entries = new MapiAddress[nNewRecips]; if (nNewRecips == 0) { return(entries); } // prepare managed recipient object int size = Marshal.SizeOf(typeof(MapiRecipDesc)); MapiRecipDesc recip = new MapiRecipDesc(); // retrieve unmanaged memory blocks for (int i = 0; i < nNewRecips; i++) { // copy current array element to managed memory lpNewRecips.GetMemory(i * size, recip); // HACK: Outlook Express inverts the order of selected entries. // We re-invert the order since OE is the most likely client. int index = (int)(nNewRecips - i - 1); // store entry name and address entries[index] = new MapiAddress(recip.lpszName, recip.lpszAddress); } return(entries); } finally { // release unmanaged memory block if (lpNewRecips != null) { lpNewRecips.Dispose(); } // restore original working directory Directory.SetCurrentDirectory(currentDir); } }