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
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();