Create a vote in an EmailMessage with the extendedProperties field (EWS) - outlook

I am stuck with the problem that if I am trying to create a vote by setting the ExtendedProperty in an EmailMessage it wont show up in the Email. This is what I got so far:
Guid MyPropertySetId = new Guid("{00020329-0000-0000-C000-000000000046}");
ExtendedPropertyDefinition extendedPropertyDefinition = new ExtendedPropertyDefinition(MyPropertySetId, 0x00008520, MapiPropertyType.String);
MessageToAddTo.SetExtendedProperty(extendedPropertyDefinition, "yes;no");
I thought I finally have to right solution after reading this post: How to access extended properties set with EWS when accessing the item in VSTO for Outlook
The property is definitly set when sending the mail but when I am receiving the mail the vote is missing.

While you trying to set the correct property the PidLidVerbStream
property http://msdn.microsoft.com/en-us/library/ee218541(v=exchg.80).aspx is a binary property with a complex byte stream value as documented above. Here's some examples of setting that https://gsexdev.blogspot.com/2015/01/sending-message-with-voting-buttons.html and https://gsexdev.blogspot.com/2015/08/owa-voting-button-compose-app-for.html. For your property definition you just need
ExtendedPropertyDefinition extendedPropertyDefinition = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Common, 0x00008520, MapiPropertyType.Binary);

Related

Outlook flickering on adding too much recipients to "To" field when composing a new e-mail

I have an VSTO Outlook Add-in. In compose windows, every time a recipient is added to the "To" field, I iterate over all the recipients to search for some recipients not satisfying a particular condition. I add the ones that do not comply some rules to a List of strings. This list contains the displays names or e-mail addresses of the recipients that didn't comply the rules (I am not creating a list of Outlook COM objects).
I have noticed that the more recipients I add to the "To" field, the more slow Outlook it is by processing all them. I don't know what is Outlook internally doing for each recipient but I can see each of them are underlined maybe because they are resolved fine for Outlook, I don't know. During this process I can see that the "To" field is flickering too much.
Why is it happening? The culprit is my VSTO Add-in or the Outlook itself that it is not able to process well too much recipients and it has difficulties.
I simply do this:
List<string> recipientsNotSatisfyingCondition = new List<string>();
Outlook.Recipients recipients = this.MyMailItem?.Recipients;
try
{
for (int i = 1; i <= recipients.Count; i++)
{
Outlook.Recipient recipient = recipients[i];
if (recipient_does_not_complains_some_rules)
{
recipientsNotSatisfyingCondition.Add(recipient.Name ?? recipient.Address);
}
if (recipient != null)
{
Marshall.ReleaseComObject(recipient);
recipient = null;
}
}
}
catch (Exception ex)
{
// Log error
}
finally
{
if (recipients != null)
{
Marshall.ReleaseComObject(recipients);
recipients = null;
}
}
The code looks good. But I'd suggest calling the Recipients.ResolveAll method which attempts to resolve all the Recipient objects in the Recipients collection against the Address Book before iterating over all recipients in the collection and getting the Address property.
On the Extended MAPI level, there is no "recipient" object - recipients are stored in an IMAPITable object (IMessage::GetRecipientTable) that stores all recipients, and the whole table can be retrieved in a single call using IMAPITable::QueryRows or HrQueryAllRows. That would require Extended MAPI (C++ or Delphi), but the bigger problem is that you are working with a new message that might not be saved yet and the changes made on the OOM or Outlook UI level are not yet committed to the underlying MAPI object (IMessage). You can call MailItem.Save before retrieving IMessage object from MailItem.MAPIOBJECT and recipients using IMessage::GetRecipientTable / HrQueryAllRows, but saving the message might be undesirable.
If using Redemption (any language, I am its author) is an option, you can bypass OOM (and thus eliminate the flickering) using SafeMailItem object. It also exposes Commit method that forces Outlook to commit the data to the IMessage object without saving it in the Drafts folder and preserves the item's dirty state.
As a quick test, does the following script cause flickering? You can run it in OutlookSpy (I am also its author) - open a draft message with a large number of recipients, click Script button on the OutlookSpy ribbon, paste the script, click Run:
set sItem = CreateObject("Redemption.SafeMailItem")
sItem.Item = Application.ActiveInspector.CurrentItem
sItem.Commit 'commit changes to MAPI without saving the message
for each recip in sItem.Recipients
Debug.Print recip.Address
next

Retrieve Plugin not getting triggered

We are on Dynamics CRM 2016 On-Premise. Using a plugin I'm trying to automatically update a field when a user open the CRM Account form, in this example to value "5". Here's my code:
var targetEntity = (Entity)context.OutputParameters["BusinessEntity"];
if (targetEntity == null)
throw new InvalidPluginExecutionException(OperationStatus.Failed, "Target Entity cannot be null");
var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
var service = serviceFactory.CreateOrganizationService(context.UserId);
if (targetEntity.Attributes.Contains("MyField"))
fedTaxId = targetEntity.Attributes["MyField"].ToString();
targetEntity.Attributes.Add("MyField"d, "5");
targetEntity["MyField"] = "5";
service.Update(targetEntity);
I list this in message type 10 (Before Main Operation Outside Transaction).
In Plugin Registration I list this as Post Operation stage and Synchronous.
However when I open the Account form, the page blinks once but the value did not get automatically populated. There is no javascript that would've manipulated this form or value either.
Any suggestion? Thanks.
Two options:
Add a script on the form setting the field value on load. Keep in mind this script should only do its thing if the form type = 2.
(Not recommended) Register a plugin on the synchronous post retrieve message for the entity. Make sure this step sets the field value on the entity object in the OutputParameters collection. Now, keep in mind your form will not be aware of the fact that this field has been modified, so it will not be flagged dirty and it will not automatically be submitted when record changes are being saved. So, in this scenario you would still need to add some JavaScript OR you would need an extra plugin registered on the pre update message of the entity setting the field as desired.

How to get smtp address of current Outlook store

We have user with 3-4 shared email address in Outlook.
I am developing add-in where it will extract the email address of selected store and will get it's contact folder from People.
My problem is I don't know how to get email address of SelectedStore.
Here is my code.
string recipientName = SelectedStore.EmailAddress; // This is what I want to make it work
Outlook.Recipient recip = ns.CreateRecipient(recipientName);
recip.Resolve();
if (recip.Resolved)
{
Outlook.MAPIFolder folderContacts = ns.GetSharedDefaultFolder(recip, Outlook.OlDefaultFolders.olFolderContacts);
}
Any help will be appreciated.
Thank you.
For the mailbox owner, you can either try to read the MAPIFolder.Store property to get to the parent store, then read the PR_MAILBOX_OWNER_ENTRYID property (DASL name "http://schemas.microsoft.com/mapi/proptag/0x661B0102") using Store.PropertyAccessor.GetProperty. You can then use the store owner entry id to call Namespace.GetAddressEntryFromID. Once you have the AddressEntry object, you can use AddressEntry.GetExchangeUser.PrimarySmtpAddress.
Note that PR_MAILBOX_OWNER_ENTRYID property is only available in the online stores. You might want to use Redemption (I am its author) and its RDOExchangeMailboxStore.Owner.SmtpAddress property. RDOExchangeMailboxStore can be retrieved using RDOSession.GetRDOObjectfromOutlookObject(Store) or using RDOSession.GetStoreFromID.
You can also try to retrieve the store entry id and parse it - its format is documented and you can extract the EX type address of the owner. You can then construct the GAL entry id to open the AddressEntry object. From there, you can retrieve the SMTP address.
Just to let you know, I found the solution.
Outlook.MAPIFolder folderContacts = store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
should do the trick.

Access MailItem properties of Outlook msg attachment

I'm trying to use vbscript to extract mail item details from hundreds of old Exchange Journal Outlook PST files. All the items in the PST archives are made up of an "envelope" mail item with an .msg attachment that's the actual e-mail whose properties I want to capture.
I can access the attachment object, but cannot extract the MailItem properties and collections listed below, presumably because the attachment isn't opening as a Mail Item. I've tried to use the PropertyAccessor object, but I can't get any results from it.
The only workaround I've come up with is to use the SaveAsFile method to save each attachment to file, then CreateItemFromTemplate to open the saved file, which then provides full access to the Mail Item properties of the object. However, the delay caused by the disk operations is excessive. My basic "workaround" code for returning a "objMsg" MailItem object is:
Set objOL=WScript.CreateObject("Outlook.Application")
set objNS=objOL.GetNameSpace("MAPI")
Set objPST = objNS.Folders(strPSTname).Folders("Inbox").Items
Set objItem = objPST.Items(1)
objItem.Attachments(1).SaveAsFile(conTempPath)
Set objMsg = objOL.CreateItemFromTemplate(conTempPath)
Is anyone aware of a better method for accessing the Mail Item properties of a .msg attachment?
objItem.Class
objItem.ReceivedTime
objItem.SenderEmailAddress
objItem.SenderName
objItem.SentOnBehalfOfName
objItem.Subject
objItem.Attachments
objItem.Recipients
objItem.To
objItem.Cc
objItem.Bcc
This is the best you can do in the Outlook Object Model. Your options are:
Extended MAPI (usable from either C++ or Delphi) - call IAttach::OpenProperty(PR_ATTACH_DATA_OBJ, IID_IMessage, ...)
Redemption (I am its author), which is usable from any language - its RDOAttachment object exposes the EmbeddedMsg property.

Outlook Add-In : Get Contact from Mail

I am doing a bit add-in development for outlook 2010 and I'm trying to get the ContactItems associated to an email (MailItem). I think the MailItem.Links collection should return what I want, but it's empty. Maybe I'm on the wrong path, but I'm out of ideas at the moment.
I have an Outlook.MailItem and I like to get the associated Outlook.ContactItem. When you open a mail with outlook and hover over the mail-adresses a contact-popup appears, so the link must be somewhere in the MailItem, but I don't know where.
For example, I tried using the MailItem.Links collection which says in tooltip that it represents the contacts to which the item is linked.
Explorer explorer = application.ActiveWindow() as Explorer;
MailItem mail = explorer.Selection as MailItem;
foreach (Link l in mail.Links)
{
System.Diagnostics.Debug.WriteLine("Link: " + l.Name);
}
The MailItem so far is correct, I can do whatever I want with it but
the MailItem.Links collection is empty.
You should try using the MailItem.Recipients collection which contains the addresses where the message will or has been be sent to (i.e. To, CC, BCC). You will have to check the Recipient.AddressEntry to see if the address exists in the Contacts Address Book (CAB) via GetContact, otherwise you will have to resolve it using ExchangeUser via GetExchangeUser.
The AddressEntry.AddressEntryUserType will tell you what type of recipient is included in the message - Exchange User or List, CAB, or basic SMTP address.

Resources