EWS - Outlook Interop Synchronize - c#

I'm using ExchangeServer 2010 SP2
and Outlook 2013
First I'm saving a Mail to the Draft folder using EWS
EmailMessage.Save()
After that I'm trying to open the mail via Interop
but I'm getting a COMException that the item doesn't exist
Outlook.Application app = new Outlook.Application();
Outlook.NameSpace mapi = app.GetNamespace("MAPI");
Outlook.MAPIFolder draftFolder = mapi.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderDrafts);
//Custom function to get EntryID
string entryId = GetMessageId(email,IdFormat.HexEntryId);
string storeId = draftFolder.StoreID;
MailItem item = null;
try
{
item = mapi.GetItemFromID(entryId, storeId);
}
catch (COMException)
{
//Item not found
}
Is there any way to force Outlook to sync the Draft folder with the Exchange server?
I have used
Session.SendAndRecieve(true)
but it doesn't show any effect and I can't find any other Interop functions doing the desired thing.
EDIT: When disabling Cache-Mode everything runs fine but as soon as I turn it on I have no clue how to force it to get the Message
Thank you very much!

You can either
wait until the sync finishes - use Namespace.SyncObjects collection, retrieve the first SyncObject object, call SyncObject.Start and wait for the SyncObject.SyncEnd event to fire.
On the Extended MAPI level (C++ or Delphi) or Redemption (I am its author, it wraps Extended MAPI and can be used in any language), open the message in the online mode by using the MAPI_NO_CACHE (0x200) flag (IMsgStore::OpenEntry in Extended MAPI or RDOStore.GetMessageFromID in Redemption).

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.

can i change incoming mail label in outlook to another label using c#?

I am creating outlook add ons. I want when mail come inbox then change
the label, i use Outlook.ItemsEvents_ItemAddEventHandler(callBack)
method but in work only when outlook web app open. I want
Outlook.ItemsEvents_ItemAddEventHandler(callBack) call everytime
when mail comes in Inbox.
If there is ant Outlook Rest Api available for that problem.
private void Phishing_Load(object sender, RibbonUIEventArgs e)
{
outlookApp = new Outlook.Application();
inboxFolder = outlookApp.ActiveExplorer().Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
deleterFolder = outlookApp.ActiveExplorer().Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderJunk);
mailItems = inboxFolder.Items;//.Restrict("[Unread]=true");
mailItems.Sort("[ReceivedTime]", true);
inboxFolder.Items.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(CallFunction);
}
private void CallFunction(object data)
{
MessageBox.Show("call function");
}
Outlook add-in can work only when Outlook application is running. It seems you can't get what you wish using an Outlook add-in - find an alternative way. If you run Outlook against on-site Exchange server try to create a so called transport agent for Exchange.

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 Redemption : How to Access RDORules or rules from outlook in c#

I am using Outlook redemption to access all rules from outlook.
How could we get RDORules using Outlook Redemption in c# ?
I have tried accessing this using below code
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook._NameSpace ns = app.GetNamespace("MAPI");
Redemption.RDOSessionClass rdoSession = new Redemption.RDOSessionClass();
rdoSession.MAPIOBJECT = ns.MAPIOBJECT;
rdoSession.Stores.DefaultStore.Rules - Here Rules property not exist.
The reason is rdoSession.Stores.DefaultStore return RDOStore object and Rules property exist in RDOExchangeStore object.
and i am not able to access RDOExchangeStore object. cause store kind is
"skPstUnicode"
Is there any way to access RDORules ?
Could be a couple of things up here .. have you iterated through the stores to find the exchange store ? as it looks like that you are not connected to exchange or the default store is configured to be a PST.
Update: to Answer your extra questions.
You can use RDO directly against the Exchange Server i.e Out side of outlook as long as you are online
Redemption.RDOSession rdoSession = new Redemption.RDOSession();
Use the logon method on the RDOSession object.

Categories

Resources