Jarrod566966

Hello,

I would like to create an outlook add-in that simply adds a custom bit of header information to every outgoing mail message. I have searched all day for information on this topic, and I would just like somebody to point me in the direction I need to go. I don't want to use CDO or Redemption (costs $200). I can easily use the propertyaccessor in Outlook 2007 to read the header, but you cannot set this property. Also, I need to support Outlook 2003. I also have a class I modified from http://www.outlookcode.com/codedetail.aspx id=1112. It uses mapi32 directly with interop, and I can get the header information easily, but it does nothing when I try to set it. Even if it comes down to me having to write a com component in c++, where is a good resource to get started with that. Is there a MAPI SDK anymore

Any help would be appreciated.

Jarrod


Re: Visual Studio Tools for Office Add header to outgoing mail

Sue Mosher - Outlook MVP

Are you using the right namespace This works fine here:

oPA.SetProperty("http://schemas.microsoft.com/mapi/string/" & _
"{00020386-0000-0000-C000-000000000046}/" & Prop, Val)

where oPA is the PropertyAccessor, Prop is the string for the x-header name and Val is the string value for that header. Make sure you do something to "dirty" the item after you set the X-header, such as setting the Subject value, and then save it.

Of course, if you want to support Outlook 2003, then PropertyAccessor is irrelevant. Helmut's MAPI32 technique ought to work. Yes, there is still a MAPI SDK and MAPI discussion groups; see http://www.outlookcode.com/d/mapi.htm





Re: Visual Studio Tools for Office Add header to outgoing mail

Jarrod

Sue, you appear to the the authority on outlook, thanks for your help.

I finally got the PropertyAccessor to work as per your post. I was using the PropertyTag format and when I used the string format as you suggested it worked. But as you mentioned, I would like to support 2003 so this is irrelevant. I would like to get Helmut's technique to work. Here is the method I have been using, taken from Helmut's post. What do I need to do to get this to work I see he is using the propertytags, so how can I modify this to set the header Thanks again.

Code Snippet


private static void SetMessageProperty(object mapiObject, uint propertyTag, string text)
{
// Pointer to IUnknown Interface
IntPtr IUnknown = NULL;

// Pointer to IMessage Interface
IntPtr IMessage = NULL;

// Pointer to IMAPIProp Interface
IntPtr IMAPIProp = NULL;

// Structure that will hold the Property Value
SPropValue propValue;

// A pointer that points to the SPropValue structure
IntPtr ptrPropValue = NULL;

// if we have no MAPIObject everything is senseless...
if (mapiObject == null) return;

try
{
// We can pass NULL here as parameter, so we do it.
MAPIInitialize(NULL);

// retrive the IUnknon Interface from our MAPIObject comming from Outlook.
IUnknown = Marshal.GetIUnknownForObject(mapiObject);

// since HrGetOneProp needs a IMessage Interface, we must query our IUnknown interface for the IMessage interface.
// create a Guid that we pass to retreive the IMessage Interface.
Guid guidIMessage = new Guid(IID_IMessage);

// try to retrieve the IMessage interface, if we don't get it, everything else is sensless.
if (Marshal.QueryInterface(IUnknown, ref guidIMessage, out IMessage) != S_OK) return;

// create a Guid that we pass to retreive the IMAPIProp Interface.
Guid guidIMAPIProp = new Guid(IID_IMAPIProp);

// try to retrieve the IMAPIProp interface from IMessage Interface, everything else is sensless.
if (Marshal.QueryInterface(IMessage, ref guidIMAPIProp, out IMAPIProp) != S_OK) return;

// double check, if we wave no pointer, exit...
if (IMAPIProp == NULL) return;

// Alloc memory for the text and create a pointer to it
IntPtr ptrToValue = Marshal.StringToHGlobalAnsi(text);

// Create our structure with data
propValue = new SPropValue();
// Wich property should be set
propValue.ulPropTag = propertyTag;
propValue.dwAlignPad = 0;
propValue.Value = (long)ptrToValue;

ptrPropValue = Marshal.AllocHGlobal(Marshal.SizeOf(propValue));
Marshal.StructureToPtr(propValue, ptrPropValue, false);

// try to set the Property ( Property Tags can be found with Outlook Spy from Dmitry Streblechenko )
HrSetOneProp(IMAPIProp, ptrPropValue);

Marshal.FreeHGlobal(ptrPropValue);
Marshal.FreeHGlobal(ptrToValue);
}
catch (System.Exception ex)
{
}
finally
{
// Free used Memory structures
if (ptrPropValue != NULL) MAPIFreeBuffer(ptrPropValue);

// cleanup all references to COM Objects
if (IMAPIProp != NULL) Marshal.Release(IMAPIProp);
if (IMessage != NULL) Marshal.Release(IMessage);
if (IUnknown != NULL) Marshal.Release(IUnknown);
MAPIUninitialize();
}
}






Re: Visual Studio Tools for Office Add header to outgoing mail

Sue Mosher - Outlook MVP

I would suggest that you post a comment in response to Helmut's original code sample, providing the link to this discussion (so you don't have to duplicate the code posting). He drops in here, as well, so if it's in both places, eventually he should see it.



Re: Visual Studio Tools for Office Add header to outgoing mail

X4U

Hi all,

I've seen this Post and I have no finnished sample for this.

But you have my proof of concept code already that can read and write properties.

You can do it also with redemption: see http://www.dimastr.com/redemption/

Dmitry has shown us the way to do it:

tag = sItem.GetIDsFromNames("{00020386-0000-0000-C000-000000000046}", "x-test-header")
tag = tag or &H1E 'the type is PT_STRING8
sItem.Fields(Tag) = "test value"

I will try to create a sample C# snippet - but it takes a little time to hack this out.

If I got it I will post it here - on my and on Sue's site.

Greets, Helmut






Re: Visual Studio Tools for Office Add header to outgoing mail

Jarrod

Helmut,

Thanks alot for taking a look at this. I figured we would need to interop with GetIDsFromNames, but I am pretty new at interop, so I really appreciate any help you could give me with that C# code. As, I said, I was trying to avoid using redemption simply because I hate to have to pay for the license when I think this is the only thing I would really need it for. I believe a method for doing this without any other libraries would be helpful to many judging from the number of posts I have seen on this topic.

Thanks, Jarrod




Re: Visual Studio Tools for Office Add header to outgoing mail

X4U

Hello Jarrod,

I played around and I wasn't able to get it working.

I'm stucking at one point where I have a handle as Int32Ptr and I simply can't execute a function wich isn't defined.

So the Idea is to define an IMAPIProp Interface and convert the Int32Ptr to this Interface and the execute the Method.

I will try my best (In my spare time) to get it working - but if you need it quick: You should get Redemption

Greets Helmut






Re: Visual Studio Tools for Office Add header to outgoing mail

Jarrod

Yeah, we are looking at redemption right now. I really appreciate your help. That interop stuff gets really messy so if you can get this working it would be great, but if not I think we may end up using redemption. We have to get this one way or another...

Jarrod




Re: Visual Studio Tools for Office Add header to outgoing mail

Mike Morton - MSFT

Jarrod, can I mark this as answered or were there outstanding issues

Mike





Re: Visual Studio Tools for Office Add header to outgoing mail

X4U

Hello Jarrod,

I have written an Article that addresses this and brings you the solution.

I hope this helps.

see: http://www.codeproject.com/useritems/BridgingTheGap.asp

Greets, Helmut