Outlook.MailItem.UserProperty disappear after sending mail - c#

I'm trying to add custom UserProperty to MailItem while creating it.
I add an attachement's Hash as UserProperty to my MailItem object.
Then I open my new MailItem in Outlook.
mi = olApp.CreateItem(Outlook.OlItemType.olMailItem) as Outlook.MailItem;
Outlook.UserProperties mailUserProperties = null;
Outlook.UserProperty mailUserProperty = null;
mi.Attachments.Add(file.FilePath);
mailUserProperties = mi.UserProperties;
mailUserProperty = mailUserProperties.Add("AttachementsHash", Outlook.OlUserPropertyType.olText);
mailUserProperty.Value = file.Hash;
mi.Save();
mi.Display();
If I check MailItem.UserProperties using OutlookSpy BEFORE sending I see that my mail has one UserProperty.
Then I click "Send Mail" in Outlook and I check my mail in SentItems folder.
I can see UserProperties.Count == 0.
If anyone knows why my UserProperty disappear, please help me and tell :)

With a lot of effort i resolved my problem.
UserProperties are removed after sending mail. But in stead of UserProperties I used MailItem.PropertyAccessor.SetProperty
MSDN Documentation of Property Accessor
string prop = "http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/PropertyName";
mi.PropertyAccessor.SetProperty(prop, propertyValue.ToString());
And then on event 'ItemAdd' I checked, if item was added to sentItems.
If it Was added to sentItems I read properties using such construction:
Outlook.MailItem AddedMail = item as Outlook.MailItem;
string attachmentProperty = AddedMail.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001E");
And then finnally I parse string in order to get my data.
I hope it will help anyone :)

Related

Getting header information using c#

I am trying to create an outlook add-in in C# which collects header information from new emails in the inbox. Googling it says to use the following code to get the header information for the email.
mailitem.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001F/")
However when I use this the error Object reference not set to an instance of an object. Click the schema address also says the resource is no longer there is there another way of getting this or do I need to use a different language?
For reference I have added the below.
private void Quarantine()
{
Outlook.MAPIFolder inBox = (Outlook.MAPIFolder)this.Application.
ActiveExplorer().Session.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderInbox);
Outlook.Items items = (Outlook.Items)inBox.Items;
Outlook.MailItem MailItem = null;
items.Restrict("[UnRead] = true");
var destFolder = inBox.Folders["test"];
string StrRegex = #"(Final Score - [-][0-9] | Final Score - [2][0 - 1] | Final Score - [0 - 1][0-9])";
Regex Reg = new Regex(StrRegex);
foreach (object email in items)
{
MailItem = email as Outlook.MailItem;
String Header= MailItem.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001F/");
if (!(Reg.IsMatch(Header)))
{
MailItem.Move(destFolder);
}
}
}
}
as operator will return null is the object is not a MailItem. Your code never checks for that. You can have objects other than MailItem in the Inbox folder, such as ReportItem, MeetingItem, etc.

store permanently properties in mailitem and related .msg file

I need to save permanently some custom information inside an Outlook Mailitem and retrieve them back.
My case scenario is the following: I select an email in Outlook 2013 explorer, write inside that email some information, save it on my disk as .msg file, delete the email from the Inbox Outlook folder, open the .msg file as Outlook.MailItem and read that information in order to keep them or change them.
I'm using the Outlook.ItemProperties.Add() method to add a custom ItemProperty inside the selected MailItem.
When I get a MailItem from the .msg I'm not able to find that properties.
I've used OutlookSpy->Miscellaneous->OpenIMsgOnIstg function to check the .msg and I've noted that all properties are in the GetProps tab.
My question is: How can I read the properties?
Here is the code to write the properties and save the mail as .msg:
Outlook.Application outApp= new Outlook.Application();
Outlook.MailItem mail= null;
try { mail = (Outlook.MailItem)outApp.ActiveInspector().CurrentItem; }
catch {
if (outApp.ActiveExplorer().Selection.Count > 0)
mail = (Outlook.MailItem)outApp .ActiveExplorer().Selection[1];
else { // ERROR }
}
Outlook.ItemProperty prop01 = mail.ItemProperties.Add("MyProperty01", Outlook.OlUserPropertyType.olText);
prop01.Value = "hola";
Outlook.ItemProperty prop02 = mail.ItemProperties.Add("MyProperty02", Outlook.OlUserPropertyType.olNumber);
prop02.Value = 23;
mail.Save();
mail.SaveAs(#"C:\WorkSpace\mail.msg", Outlook.OlSaveAsType.olMSG);
if (mail != null) Marshal.ReleaseComObject(mail);
if (outlookObj != null) Marshal.ReleaseComObject(outApp );
Here is my code to read the properties from the .msg after I've deleted the email in Outlook:
Outlook.Application outApp= new Outlook.Application();
Outlook.MailItem msgMail=(Outlook.MailItem)outApp.CreateItem(Outlook.OlItemType.olMailItem);
msgMail = (Outlook.MailItem)outApp.Session.OpenSharedItem(#"C:\WorkSpace\mail.msg");
Outlook.ItemProperties mailProps = msgMail.ItemProperties;
Outlook.ItemProperty pr = mailProps["MyProperty01"]; // pr IS NULL
But OutlookSpy shows the properties are in the .msg file.
I have solved my problem following this bypassing solution.
Use Mailitem.PropertyAccessor.GetProperty and pass the DASL property name shown by OutlookSpy (I am its author).

Not setting the property of incoming mails in MS Outlook 2010

I am setting the property (for making them As Read and with High Importance) of the mail those are coming to the MS Outlook 2010 inbox using below code -
Microsoft.Office.Interop.Outlook.Application myApp = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.NameSpace mapiNameSpace = myApp.GetNamespace("MAPI");
Microsoft.Office.Interop.Outlook.MAPIFolder myInbox = mapiNameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
int i = myInbox.Items.Count;
((Microsoft.Office.Interop.Outlook.MailItem)myInbox.Items[i]).UnRead = false;
((Microsoft.Office.Interop.Outlook.MailItem)myInbox.Items[i]).Importance = OlImportance.olImportanceHigh;
This works fine when only one mail comes at a time (I can see the mail as Read and with High Importance) after the code execution but when three or four mails coming at a time then it set the property of only one mail not for all the three or four mails.
Please suggest.
Remember to save the message after setting any property.
Most importantly, your code uses multiple dot notation - for each ".", you get back a brand new COM object, so you end up setting Importance property on an object different from the one used to set the UnRead property.
int i = myInbox.Items.Count;
MailItem msg = (Microsoft.Office.Interop.Outlook.MailItem)myInbox.Items[i];
msg.UnRead = false;
msg.Importance = OlImportance.
msg.Save();
Another problem is that you assume that the last item in the Items collection is the latest one. This is not generally true. As cremor suggested, use Items.ItemAdd event, but still do not forget to save the message.
You can use the ItemAdd event of the Items property of the folder:
Items inboxItems = myInbox.Items;
inboxItems.ItemAdd += HandleItemAdded;
private void HandleItemAdded(object item)
{
MailItem mail = item as MailItem;
if (mail == null) { return; }
mail.UnRead = false;
mail.Importance = OlImportance.olImportanceHigh;
}

Retrieve Current Email Body In Outlook

in my outlook addin I want to add a button on the Ribbon so when user click this button I want to retrieve the current selected email's body , I have this code but it retrieve only the first email from the inbox because the index is 1 :
Microsoft.Office.Interop.Outlook.Application myApp = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.NameSpace mapiNameSpace = myApp.GetNamespace("MAPI");
Microsoft.Office.Interop.Outlook.MAPIFolder myInbox = mapiNameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
String body = ((Microsoft.Office.Interop.Outlook.MailItem)myInbox.Items[1]).Body;
so how to retrieve the current opened email in outlook? , this method work for me but I need to get the index for the current email.
Thanks.
You shouldn’t initialize a new Outlook.Application() instance each time. Most add-in frameworks provide you with an Outlook.Application instance, corresponding to the current Outlook session, typically through a field or property named Application. You are expected to use this for the lifetime of your add-in.
To get the currently-selected item, use:
Outlook.Explorer explorer = this.Application.ActiveExplorer();
Outlook.Selection selection = explorer.Selection;
if (selection.Count > 0) // Check that selection is not empty.
{
object selectedItem = selection[1]; // Index is one-based.
Outlook.MailItem mailItem = selectedItem as Outlook.MailItem;
if (mailItem != null) // Check that selected item is a message.
{
// Process mail item here.
}
}
Note that the above will let you process the first selected item. If you have multiple items selected, you might want to process them in a loop.
On Top add reference to
using Outlook = Microsoft.Office.Interop.Outlook;
Then inside a method;
Outlook._Application oApp = new Outlook.Application();
if (oApp.ActiveExplorer().Selection.Count > 0)
{
Object selObject = oApp.ActiveExplorer().Selection[1];
if (selObject is Outlook.MailItem)
{
Outlook.MailItem mailItem = (selObject as Outlook.MailItem);
String htmlBody = mailItem.HTMLBody;
String Body = mailItem.Body;
}
}
Also you can change the body which will show in outlook before viewing the mail.

Is there no way to obtain sender's emailId from outlook calender data using Microsoft.Office.Interop , c#.net

I want to get the sender's emailId.
I am able to read all the data of calender by the below code but not the sender's emailId.
using Microsoft.Office.Interop.Outlook;
Microsoft.Office.Interop.Outlook.Application outlook = new Application();
Microsoft.Office.Interop.Outlook.NameSpace oNS = outlook.GetNamespace("MAPI");
oNS.Logon(Missing.Value, Missing.Value, true, true);
string currentUserEmail = oNS.CurrentUser.Address;
string currentUserName = oNS.CurrentUser.Name;
// Get the Calendar folder.
Microsoft.Office.Interop.Outlook.MAPIFolder objMAPIFolder =oNS.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
//Get the Sent folder
MAPIFolder sentFolder = oNS.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderSentMail);
Items sentMailItems = sentFolder.Items;
Items items = objMAPIFolder.Items;
foreach (object item in sentMailItems)
{
if (item is MailItem)
{
MailItem oneMail = item as MailItem;
string mailContent = oneMail.HTMLBody;
//item.sender is not available
}
}
foreach (object item in items)
{
if (item is Microsoft.Office.Interop.Outlook.AppointmentItem)
{
Microsoft.Office.Interop.Outlook.AppointmentItem mitem = item as Microsoft.Office.Interop.Outlook.AppointmentItem;
string subject = mitem.Subject;
DateTime start = mitem.Start;
DateTime end = mitem.End;
string body = mitem.Body;
string location = mitem.Location;
string entryId = mitem.EntryID;
//sender email id not available
//string senderEmail = mitem.sender;
}
}
oNS.Logoff();
But in any case whether reading appointments or sent folder emails, I am unable to obtain the sender's email Id.
does anybody have any solution for this problem ?
I think you can get the name from mitem.organizser and then look at the Recipients to find the match..
Then look up the email address via a mapi property PR_SMTP_ADDRESS using a PropertyAccessor.
AppoitnmentItem.GetOrganizer() is not necessarily the sender of the appointment. In a shared calendar (chief/secretary), they might be different.
You can get the sender from an appointment using
AppointmentItem.SendUsingAccount
But from my experience (outlook 2010), that property returns null unless you are logged in as the sender. But it is useful to check if the organizer is different than the sender anyway.

Categories

Resources