|
|
|||
| Outlook and .NET Printer Friendly Version | |||
|
|
Writing code with C# and VB.NET to create Outlook add-ins and other projects | ||
| Topic | |||
|
|
PR_SENDER_EMAIL_ADDRESS != SMTP address in Exchange environment?
Hi folks, I've been muddling my way through an Outlook add-on in VS 2008, targeting .NET 2.0 and Outlook 2003 SP3. I wanted to retrieve the SMTP form of the email address for the senders of Exchange email, so that I could use it to draw a small WinForm, query SharePoint for properties of the MySite page, and give the user some additional context beyond what appears in the Outlook Address Book. Well, that's the theory, and while I've come around to the MAPI interop approach that Helmut Obertanner open-sourced (http://www.x4u.de/LinkClick.aspx?link=downloads%2fMAPITest.zip&tabid=61&mid=451), and I've coded everything twice to make sure I didn't screw something up badly, I still cannot seem to retrieve the SMTP address using the PR_SENDER_EMAIL_ADDRESS property - only the X.500 equivalent (e.g. /O=COMPANY,/OU=REGION,/CN=EMPLOYEES,/CN=LAST, FIRST). So I finally downloaded MfcMapi.exe from Microsoft, and dug into the MAPI properties of my Inbox. From what I'm seeing there, it appears that the .NET code is working correctly, but somehow our Exchange/Outlook environment is giving me the X.500 address instead of the SMTP address for the PR_SENDER_EMAIL_ADDRESS property. Is this even possible? In all the online postings I've reviewed, no one has ever hinted that this might occur, or that a VSTO add-in in an Exchange environment would ever have to find some *other* MAPI property to get the SMTP address for the sender of received emails. Perhaps our Exchange admins messed something up long ago and can't ever fix it, or perhaps I've just simply misread something and need to find another approach that will retrieve SMTP address from senders of received emails. I'll go whichever way works, but I'm feeling stuck and could really use some encouraging words at this point. Thanks for any hints, ideas or assistance anyone could provide. Mike Smith-Lonergan 26-Jun-2008 23:35 |
||
|
|
Sue Mosher
27-Jun-2008 08:21
Since the user may be using Cached Exchange mode, you need to take a bit different approach; see http://groups.google.com/group/microsoft.public.outlook.program_vba/browse_frm/thread/4d4d5fece24a2a7/ad2fcbb691d5bf18 Another option would be to use ADSI techniques to perform a lookup directly on the GAL, rather than through Outlook. FWIW, Outlook 2007 resolves this issue by explictly exposing the SMTP address in the Outlook object model. |
||
|
|
Mike Smith-Lonergan
27-Jun-2008 19:41
Sue, thank you! I guess I should've done more digging around the 'net to find this kind of hint, but I really didn't know what could be causing this, and not seeing any hints of it so far led me to conclude there wasn't a widely-understood cause. Live & learn. :) I've pored over the discussion thread you included, and I think the best I've been able to figure is that (in CDO/Redemption APIs) I'd want to retrieve the message object's Sender.Fields(PR_EMS_AB_PROXY_ADDRESSES).Value property that is prefixed with "SMTP:". However, I'm pretty limited in translating that into the MAPI + Win32?/COM? code that constitutes the heart of Helmut's X4UMapi code. My best guess is that to modify his GetMessageProperty() procedure to parse out the "SMTP:" Value, I'd need to: - (1) declare an array variable of pointers in place of "ptrPropValue" - (2) declare a similar array variable of Structures in place of "propValue" - (3) possibly change the Marshal.PtrToStructure() call to handle multi-value output - (4) possibly change the Marshal.PtrToStringAnsi() call to handle multi-value input - (5) add a little logic to loop through the multiple propValue.Value properties I'm pretty sure I can handle (2) and (5), but the rest are pretty much entirely foreign to me, and while I could do another few weeks' research to figure out how this code should be modified, I'm hoping the needed changes are trivial to someone with experience in this kind of code... In case you don't have a copy of Helmut's X4UMapi class handy, here's the essential code from the GetMessageProperty() procedure, where the caller was passing "PR_SENDER_EMAIL_ADDRESS" in as the propertyTag value: private static string GetMessageProperty(object mapiObject, uint propertyTag) { string messageProperty = String.Empty; IntPtr IUnknown = NULL; IntPtr IMessage = NULL; IntPtr IMAPIProp = NULL; SPropValue propValue; IntPtr ptrPropValue = NULL; try { MAPIInitialize(NULL); IUnknown = Marshal.GetIUnknownForObject(mapiObject); Guid guidIMessage = new Guid(IID_IMessage); Marshal.QueryInterface(IUnknown, ref guidIMessage, out IMessage); Guid guidIMAPIProp = new Guid(IID_IMAPIProp); Marshal.QueryInterface(IMessage, ref guidIMAPIProp, out IMAPIProp); HrGetOneProp(IMAPIProp, propertyTag, out ptrPropValue); propValue = (SPropValue)Marshal.PtrToStructure(ptrPropValue, typeof(SPropValue)); messageProperty = Marshal.PtrToStringAnsi(new IntPtr(propValue.Value)); return messageProperty; Note: SPropValue is a custom structure, and MAPIInitialize() is a custom procedure (not shown here). Q: does anyone have any suggestions on how to enable this procedure to handle a multi-value attribute returned to (what currently is represented by) the ptrPropValue variable? Thanks for any additional help you might be able to provide. Cheers, Mike |
||
|
|
Sue Mosher
27-Jun-2008 19:55
Sorry, but I don't do C# or ExMAPI. (I would use Redemption if it were my project.) All I can contribute is that you'll need an AddressEntry object in order to get at that property. You could try pinging Helmut through his web site and ask how to handle the multi-valued property. |
||
|
|
Mike Smith-Lonergan
27-Jun-2008 20:36
Thanks Sue, I've posted a message at the outlooksharp.de forums, and if anyone else has any thoughts, please let me know here (or there). |
||
|
|
|||
