0
votes
  1. I want to create a fake email in the sent items folder. To achieve this goal:

    a) I am taking a copy of a mail in unsent state

    b) Assigning a GUID as UserProperty

    c) Changing MessageClass = IPM.Post and saving

    d) Info: UserProperty is still existent here

    e) Sending PostItem

  2. Within ItemAdd event handler for sent items folder:

    a) I am checking if Item is PostItem

    b) Trying to identify the current object with the set UserProperty (this is already failing, no UserProperties available -> PROBLEM 1)

    c) Want to convert the current PostItem to MailItem by changing MessageClass = IPM.Note and saving

Even I replace 2b with identifying by using the subject instead of UserProperty (as subject is present) after sending I still see the object as PostItem (IPM.Post) and not MailItem (IPM.Note) in sent items -> PROBLEM 2.

When I do a find in sent items, lookup a specific item, change MessageClass = IPM.Note and save, the PostItem is successfully changed to a MailItem.

Regarding Problem 1: Why are the UserProperties of a PostItem not available during this event?

Regarding Problem 2: Why I cannot "convert" a PostItem to a MailItem during this event?

How I can solve this natively?

This is my code:

In ThisAddIn:

                // ItemSend Event
                Outlook.Application application = this.Application;
                application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(ItemSend_BeforeSend);


...

// ItemAdd event
                outlookNameSpace = this.Application.GetNamespace("MAPI");
                Sent_items = outlookNameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderSentMail);

                items = Sent_items.Items;
                items.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(items_ItemAdd);

...

// ItemAdd event action
                void items_ItemAdd(object Item)
                {
...
                            Outlook.PostItem postItem = Item as Outlook.PostItem;

                            Outlook.UserProperties postUserProperties = null;
                            Outlook.UserProperty postUserProperty = null;

                            // for debug only
                            MessageBox.Show(null ?? postItem.Subject, "TestApp: Info", MessageBoxButtons.OK);


                            try
                            {
                                // start of test part

                                postUserProperties = postItem.UserProperties;
                                StringBuilder builder = new StringBuilder();

                                for (int i = 1; i <= postUserProperties.Count; i++) // count is 0 here so no UserProperties !!!
                                {
                                    postUserProperty = postUserProperties[i];
                                    if (postUserProperty != null)
                                    {
                                        builder.AppendFormat("Name: {0} \tValue: {1} \n\r",
                                            postUserProperty.Name, postUserProperty.Value);
                                        Marshal.ReleaseComObject(postUserProperty);
                                        postUserProperty = null;
                                    }
                                }
                                if (builder.Length > 0)
                                {
                                    System.Windows.Forms.MessageBox.Show(builder.ToString(),
                                        "The UserProperties collection");
                                }
                                // end of test part
...
}

// ItemSend_BeforeSend event action
                void ItemSend_BeforeSend(object item, ref bool cancel)
                {
...

 Outlook.Application objOutlook = new Outlook.Application();
                Outlook.MailItem email = (Outlook.MailItem)objOutlook.Session.OpenSharedItem(MjFileMsg);

                // add we item guid to object in order to identify afterwards
                var mailUserProperty = email.UserProperties.Add("WeItemGuid", Outlook.OlUserPropertyType.olText, false, 1);

                createdWeItemGuid = Guid.NewGuid().ToString().ToLower();
                mailUserProperty.Value = createdWeItemGuid;

                email.MessageClass = "IPM.Post";
                email.Save();

                // debug only: check if value is present after changing messageclass (yes, it is present!)
                Outlook.UserProperty testProp = email.UserProperties["WeItemGuid"];
                var testVal = testProp.Value;

                email.Send();
...
}



[UPDATE 1]:

This is the updated code in ItemSend event action:


                Outlook.Application objOutlook = new Outlook.Application();
                Outlook.MailItem email = (Outlook.MailItem)objOutlook.Session.OpenSharedItem(MjFileMsg);

                // remove recipients otherwise PostItem will be sent really to recipients (but obviously causing the PostItem not to be sent !!!)
                email.To = null;
                email.CC = null;
                email.BCC = null;

// This has the same effect like setting To/Cc/Bcc to null:
/*
                foreach (Outlook.Recipient Recip in email.Recipients)
                {
                    Recip.Delete();
                }
*/

                email.MessageClass = "IPM.Post";
                email.Save();
                email.Send();
1

1 Answers

1
votes

Do you save the message after resetting the message class? Keep in mind that you will also need to wipe out the PR_ICON_INDEX property.

You cannot convert PostItem to MailItem on the fly because Outlook still references the original PostItem object. It will see your changes only after both your code and Outlook dereference the object and later reopen it.

If using Redemption is an option, it is as easy as (off the top of my head):

RDOSession session = new RDOSession();
session.MAPIOBJECT = outlookNameSpace.MAPIOBJECT;
RDOFolder folder = session.GetDefaultFolder(rdoDefaultFolders.olFolderSentMail);
RDOMail msg = folder.Items.Add("IPM.Note");
msg.Sent = true;
msg.ReceivedTime = DateRime.Now;
RDOMail originalMsg = (RDOMail)session.GetRDOObjectFromOUtlookObject(Item);
originalMsg.CopyTo(msg);
msg.Sender = session.CurrentUser;
msg.SentOnBehalfOf = session.CurrentUser;
msg.Save();