In a VSTO Outlook C# addin I want to loop through a folder of items that are all encrypted mailitems and get the EntryID or MAPIOBJECT as I plan to send it on to extended MAPI.
foreach (object olObject in folder.Items)
{
if (olObject is Outlook.MailItem olM)
{
//olM.EntryID fails
}
}
Where mailitems are encrypted with PKI and the private key is stored on a personal card inserted into the PC, the user must have at least opened 1 encrypted mailitem for the OOM to be able to read properties of a mailitem. At the time of looking at the folder items I do not know if this is the case or not.
I have found that if I cast an Outlook.Selection
to a mailitem I can then get the entryID. Would there be some way of doing the same with folder.Items?
I also note that mailItem.MAPIOBJECT will also throw an exception if no encrypted items have been viewed by the user.
The problem with hitting this error is not catching it, it is that Outlook takes too long to throw an exception. Is there any way to quickly workout that Outlook cannot read the encrypted items yet?
The only option I see at the moment is to wait for an inspector window to open on a mailitem that was encrypted. The problem with this is that if the user takes their card out then no encrypted mail items can be read.
UPDATE With respect to knowing if Outlook can read encrypted emails or not Dmitry below in the comments has confirmed you cannot, my current strategy is to listen for an inspector window to open with a mailitem that is encrypted. If this is open it means that the user has entered their pin for the card in their reader and supplied Outlook with access to their private key to decrypt that mailitem. From this point all mailitem properties like EntryID or MAPIOBJECT do not error for all mailitems, until either Outlook is closed or the card is pulled from the reader. In this case I am using Net.Pkcs11Interop to detect card readers, cards, certificates events. I am also going to check out the Windows.Devices.SmartCards Namespace in UWP world as this might be a little easier.
Do not just loop through all items in a loop - use MAPIFolder.GetTable to retrieve multiple properties from multiple items in a single call. Besides being able to retrieve the entry ids of encrypted messages, the call will also be be much faster.