Interop.Outlook - get all emails(Items) within a subfolder - c#

I'm trying to get the body(or any other attribute) of an email which is inside a specific folder in outlook.
I'm using the interop.outlook assembly.
I have done the following so far. But when trying to call an item in myInbox, there are no attributes at all.
Application myApp = new ApplicationClass();
NameSpace mapiNameSpace = myApp.GetNamespace("MAPI");
MAPIFolder myInbox = mapiNameSpace.GetDefaultFolder(OlDefaultFolders.olFolderInbox).Folders["QC"];
The following brings no expected attributes
myInbox.Items[1].
In addition, the next step is to click a link inside the body of the email. just want to know if it's even possible.
Any help will be much appreciated.

This is how I'm doing;
Outlook.Application myApp = new Outlook.Application();
Outlook.NameSpace mapiNameSpace = myApp.GetNamespace("MAPI");
Outlook.MAPIFolder myInbox = mapiNameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox).Folders["QC"];
This should bring all mails in Inbox. Then call;
Outlook.MailItem mailItem = myInbox.Items[1];
This mailItem contains all the attributes you need.
Explanation: The mailFolder.Items[1] is an Outlook.Items object which has no attributes you require. You need to cast it to an Outlook.MailItem object to achieve this.

Related

Saving html message in Outlook 2019 with .NET C#

Using .NET C# i want to load an Outlook html message from *.msg file, add a recipient and save it to standard draft folder.
I cannot do it properly with Outlook 2019 (not 2016 or 2013), because after saved, it turns the message body format to plain text. This happen with 2019 version only.
In the code example i first create the email and save it to draft. Until the COM Application object is instantiated the format remain html. Right after i had manually opened Outlook.exe the message has been turned to plain text. I check this with the function PrintBodyFormat. Please note this happen with Office 2019 only.
using Debug = System.Diagnostics.Debug;
using Outlook = Microsoft.Office.Interop.Outlook;
static void CreateMail()
{
Outlook.Application app = new Outlook.Application();
Outlook.MailItem mail = app.CreateItemFromTemplate(#"C:\html_message.msg");
mail.Recipients.Add("johndoe#foobar.com");
Debug.WriteLine(mail.BodyFormat.ToString());
//OUTPUT WITH ALL OUTLOOK VERSION: "olFormatHTML"
mail.Save();
mail.Close(Outlook.OlInspectorClose.olDiscard);
System.Runtime.InteropServices.Marshal.ReleaseComObject(mail);
mail = null;
Outlook.NameSpace nms = app.GetNamespace("MAPI");
Outlook.MAPIFolder DraftFolder = nms.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderDrafts);
mail = DraftFolder.Items[1];
Debug.WriteLine(mail.BodyFormat.ToString());
//OUTPUT WITH ALL OUTLOOK VERSION: "olFormatHTML"
mail.Close(Outlook.OlInspectorClose.olDiscard);
System.Runtime.InteropServices.Marshal.ReleaseComObject(mail);
mail = null;
app.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(DraftFolder);
System.Runtime.InteropServices.Marshal.ReleaseComObject(nms);
System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
}
//Run this after manually opened Outlook.exe
static void PrintBodyFormat()
{
Outlook.Application app = new Outlook.Application();
Outlook.NameSpace nms = app.GetNamespace("MAPI");
Outlook.MAPIFolder DraftFolder = nms.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderDrafts);
Outlook.MailItem mail = DraftFolder.Items[1];
Debug.WriteLine(mail.BodyFormat.ToString());
//OUTPUT WITH OUTLOOK 2016 OR EARLIER: "olFormatHTML"
//OUTPUT WITH OUTLOOK 2019: "olFormatPlain"
app.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(mail);
System.Runtime.InteropServices.Marshal.ReleaseComObject(DraftFolder);
System.Runtime.InteropServices.Marshal.ReleaseComObject(nms);
System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
}
Do not use mail.Close(Outlook.OlInspectorClose.olDiscard); - you never showed the inspector, so there is no reason to close it.
Also, Marshal.ReleaseComObject won't do much since you never release the Recipients collection and the Recipient object returned by Recipients.Add - both of them keep a reference to the parent message, and you end up with two implicit variables that you never release.
Do not use DraftFolder.Items[1] - save the value of MailItem.EntryID in a variable after calling Save, then use it to reopen the message using Namespace.GetItemFromID.

How to list all opened calendars in Outlook c#

How can I iterate over all opened (or maybe pinned) calendars in Outlook (as in picture below)?
The top (mine calendar) I can find by:
NameSpace mapiNamespace = outlookApp.GetNamespace("MAPI");
MAPIFolder ownerFolder = mapiNamespace.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
The below (shared calendars) I can find by:
NameSpace mapiNamespace = outlookApp.GetNamespace("MAPI");
Recipient recipient = mapiNamespace.CreateRecipient("*******Test*****");
if (recipient.Resolve())
{
MAPIFolder sharedFolder = mapiNamespace.GetSharedDefaultFolder(recipient, OlDefaultFolders.olFolderCalendar);
}
But how to iterate opened (or maybe pinned) shared calendars without knowledge of recipient?
Thank you in advance for your answer.

To filter mails from inbox which are sent to another recipient?

In Outlook Interop,
using Outlook = Microsoft.Office.Interop.Outlook;
To filter unread emails, I'm using the following code
Outlook.Application oApp = new Outlook.Application();
Outlook.NameSpace outlookNameSpace = oApp.Application.GetNamespace("MAPI");
Outlook.MAPIFolder inbox = outlookNameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
Outlook.Items items = inbox.Items.Restrict("[Unread]=true");
Likewise, Is there a way to filter the mails sent to a specific recipient other than me.
Say, filter mails sent to abc#example.com.
My mail ID would also be present in those mails in To or in CC. I will be happier to find a possible way with Outlook interop.
You can use a search query like the following to search for a match on the PR_DISPLAY_TO MAPI property (replace 0x0E04001F with 0x0E03001F for PR_DISPLAY_CC)
#SQL="http://schemas.microsoft.com/mapi/proptag/0x0E04001F" LIKE '%abc#example.com%'
Keep in mind however that PR_DISPLAY_TO / PR_DISPLAY_CC may or may not contain the email addresses; they could just contain display names.
On the Extended MAPI level (C++ or Delphi), you can create a restriction on recipients (RES_SUBRESTRICTION / PR_MESSAGE_RECIPIENTS).
If using Redemption (I am its author - any language) is an option, you can use RDOFolder.Items.Restrict - unlike Outlook Object Model, it does expand To/CC/BCC queries into recipient sub restrictions on PR_DISPLAY_NAME and PR_EMAIL_ADDRESS properties on each recipient (RES_SUBRESTRICTION / PR_MESSAGE_RECIPIENTS / RES_OR / PR_DISPLAY_NAME | PR_EMAIL_ADDRESS).
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Folder = Session.GetFolderFromID(Application.ActiveExplorer.CurrentFolder.EntryID)
set restrItems = Folder.Items.Restrict(" TO = 'abc#example.com' ")
You can also specify Recipients property in a query - it will be matched against recipients of all types (to/cc/bcc):
set restrItems = Folder.Items.Restrict(" Recipients = 'abc#example.com' ")

using Interop.outlook and ews

I am using EWS for searching for and displaying emails. However the final step of the project is to save specific messages as .msg files on the file system. I understand that this is not possible with EWS, so I will need to use Interop.Outlook to accomplish this. My question is: What is the best way to find the Outlook message given the information available from EWS. I have attempted to associate the Message.Id and ConversationId obtained from exchange via EWS with Outlook's messageId but have so far been unsuccessful.
Here is my current (failed) code for finding the ConversationID:
OUTLOOK.Application olApp = new OUTLOOK.Application();
OUTLOOK.NameSpace olNS = olApp.GetNamespace("MAPI");
OUTLOOK.MAPIFolder oFolder = olNS.GetDefaultFolder(OUTLOOK.OlDefaultFolders.olFolderInbox);
OUTLOOK.Items oItems = oFolder.Items;
String sFilter = string.Format("#SQL=\"http://schemas.microsoft.com/mapi/proptag/0x1035001F\" = '{0}'", missive.ConversationID.UniqueId);
object obj = oItems.Find(sFilter);
OUTLOOK.MailItem oEmail = (OUTLOOK.MailItem)obj;
if (oEmail != null)
{
return oEmail;
}
else
{
throw new Exception("MAIL ITEM NOT IN OUTLOOK");
}
As a side: I was looking for a reference for Outlookd filters That is the property names for the [property]=value version; and the hex values for use with the #SQL version. Does someone have a link to a good reference for that?
There's a ConvertIdType request you can use; see: https://msdn.microsoft.com/en-us/library/office/bb856559(v=exchg.140).aspx.
For a listing of MAPI properties and their DASL names and property tag values, see: https://msdn.microsoft.com/en-us/library/office/cc815517.aspx. Although Outlook Spy is a great tool for this as well.

Outlook Interop 2010 C# Moving Item to Shared OlDefaultFolders.olFolderSentMail

SOmething odd is happening. I'm trying to copy and move and item from a local MAPI folder to a remtoe Sent Items folder using GetSharedDefaultFolder. It works for the inbox folder but not sent items, even though i have permissions to it. Any ideas would be great thank you.
The Error is 'Could not complete the operation. One or more parameter values are not valid'
The code sample is:
Outlook.MailItem cItem = (mailmsg as Outlook.MailItem).Copy() as Outlook.MailItem;
Outlook.NameSpace ns = this.Application.GetNamespace("MAPI");
//ns.Logon()
Outlook.Recipient recipient = ns.CreateRecipient("realusera#domain.com");
recipient.Resolve();
if (recipient.Resolved)
{
MessageBox.Show("Resolved user");
Outlook.MAPIFolder mapifld = ns.GetSharedDefaultFolder(recipient, Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderSentMail);
cItem = (Outlook.MailItem)cItem.Move(mapifld);
}
According to MS documentation on this API, the olFolderSentMail is one of the default folders that is NOT allowed.
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook._namespace.getshareddefaultfolder.aspx
Excerpt:
FolderType can be one of the following OlDefaultFolders constants: olFolderCalendar, olFolderContacts, olFolderDrafts, olFolderInbox, olFolderJournal, olFolderNotes, or olFolderTasks. (The constants olFolderDeletedItems, olFolderOutbox, olFolderJunk, olFolderConflicts, olFolderLocalFailures, olFolderServerFailures, olFolderSyncIssues, olPublicFoldersAllPublicFolders, olFolderRssSubscriptions, olFolderToDo, olFolderManagedEmail, and olFolderSentMail cannot be specified for this argument.)

Categories

Resources