vb.net send outlook email using smtp and outlook.CreateItemFromTemplate - outlook

I would like to send an email using an SMTP server and an Outlook template as the mail message.
Dim application As New Outlook.Application
Dim path As String = "S:\TCM\Vendor.oft"
' Create a new MailItem and set the To, Subject, and Body properties.
Dim newMail As Outlook.MailItem = DirectCast(application.CreateItemFromTemplate(path), Outlook.MailItem)
Dim mail As MailMessage = DirectCast(newMail, MailMessage)
I am trying to create a mail item from a template and cast that to a MailMessage so I can use an SMTP server to send the email. However, I get the following error.
Unable to cast COM object of type 'System.__ComObject' to class type 'System.Net.Mail.MailMessage'.
Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.

There is no direct conversion between MailMessage from BCL and Outlook's MailItem. You can send the MailItem from a different account in Outlook by setting the SendUsingAccount property which allows to set an Account object that represents the account under which the MailItem is to be sent.
You may find the How To: Create and send an Outlook message programmatically article helpful.

Outlook.MailItem obviously known nothing about the System.Net.Mail.MailMessage object.
It is your responsibility to convert an Outlook message to a MIME message and/or explicitly populate all MailMessage properties before sending it.

Related

Redemption attachement filename escaping differs from Outlook

We are trying to save attachments selected by the user using Redemption but stumbled on filename escaping inconsistency between VSTO and Redemption. What we do:
By attachment context menu save attachmentSelection[1] index and filename to the db and also message entryId and storeId.
After a while (maybe even after Outlook restart) we need to save this attachment to file. To do this, we get that e-mail with Redemption by id, get attachment by index (rdoMail.Attachments[index]) and also ensure that filename match, since according to this:
https://learn.microsoft.com/en-us/dotnet/api/microsoft.office.interop.outlook.attachment.index?view=outlook-pia#Microsoft_Office_Interop_Outlook_Attachment_Index
index property is valid only during the current session. Although it is not clear what they mean. Can it change if the e-mail is saved and sent already? Or received?
For reply e-mail VSTO Attachment.Filename is "RE Test.msg" and RDOAttachment.Filename is "RE_ Test.msg" (this is msg attachment of another e-mail).
So, the questions are:
why it is different and is it documented somewhere? Can we, for example, replace _ with string.Empty for Redemption filenames or there can be other cases?
Or maybe there is a way to get RDOAttachment from Outlook Attachment object somehow?
Can we rely on that Redemption attachment index is the same as Outlook one?
Sounds like you are dealing with an embedded message attachment - unlike regular by-value attachments that expose the PR_ATTACH_LONG_FILENAME MAPI property, there is no intrinsic file name property for the embedded attachments. Both OOM and Redemption generate that property from the the embedded message subject, whcih you cam access through RDOAttachment.EmbeddedMsg.Subject. OOM does not expose embedded message attachments at all.
Yes, use RDOSession.GetRDOObjectFromOUtlookObject method
The index usually does not change, but it might. MAPI itself uses PR_ATTACH_NUM to open the attachment using IMessage::OpenAttach, but it can be different based on how the message was opened - a fake IMessage returned from MailItem.MAPIOBJECT can have a different value of PR_ATTACH_NUM from the native message returned by the store provider.

Display sender name as set in message header, instead of full name from address book

I came across this as the only other thing I could find that resembled what I'm asking: http://office-outlook.com/outlook-forum/index.php/t/84123/
I'm sending an email through Office 365's SMTP server as a notification that a form was submitted to my company email address (me#company.com) from our company RSVP email address (rsvp#company.com). I am setting the From Name to be the full name of the person filling out the form and the reply-to email as the person's email address textbox.
Here is an example of what part of the message header might look like:
To: <me#company.com>
From: Test User <rsvp#company.com>
Reply-To: <test.user#gmail.com>
In Outlook, since rsvp#company.com is an actual mailbox within our company, it automatically displays the sender name as "RSVP" (which I suppose is what was set when the mailbox was created). Is there a way to bypass this and display the sender name in the message header instead?
No. Exchange always resolves all sender and recipient names to their primary SMTP address and default name. Just the way Exchange works.
You can extract MIME headers and modify the message sender related properties on the client side after the message is received using Extended MAPI (C++ or Delphi) or Redemption (I am its author - use RDOSession.CreateOneOffEntryID / RDOSession.GetAddressEntryFromID / set RDOMail.Sender and RDOMail.Get_SentOnBehalfOf / RDOMail.Save). Note that OOM will not let you set the sender related properties even using MailItem.PropertyAccessor.

EWS -- Pop up email to be sent

I am able to create new emails using Exchange Web Service Managed API in a local desktop application. These messages contain quotes for products and services. What I want to do now is open the email before sending it so the user can edit and then send the email themselves. All users have Outlook 2013.
If you need web-client access, you should be looking at the interop libraries and not EWS. EWS is meant to be run headless without client interaction (and therefore cannot open dialogs in Outlook).
An example of doing so in the interop library would look something like:
Outlook.Application outlook = new Outlook.Application();
Outlook.MailItem email = outlook.CreateItem(Outlook.OlItemType.olMailItem)
as Outlook.MailItem;
email.To = "client#rfq.com";
email.Subject = "Your Quote";
email.Body = "Here is your quote.";
email.Attachments.Add(#"C:\quotes\quote.pdf", Outlook.OlAttachmentType.olByValue,
Type.Missing, Type.Missing);
email.Display(false);

Get/change safe senders list and blocked senders list in C# VSTO

I'm working on an Outlook 2010 add-in that needs to prompt users before following a link found in an email. During the process I'd like to offer the user the choice to trust or block the sender of the email, thus I need to access both lists. I realize that Junk/Spam email options are not exposed by Outlook OM. Although I was successful in accomplishing the task using Redemption, unfortunately I'm not allowed to use it by my employer, so I need to find another way. I found this post (Get Safe sender list in Outlook 2007 C# Add in) that points in the direction of either MAPI properties or registry keys.
My preference would be MAPI props, but I'm not sure what object that property belongs to. Would it be the property of the default store?
Outlook.Store obj = Application.Session.DefaultStore;
const string PR_SPAM_TRUSTED_SENDERS_W =
"http://schemas.microsoft.com/mapi/proptag/0x001f0418";
Outlook.PropertyAccessor pa = obj.PropertyAccessor;
string list= pa.GetProperty(PR_SPAM_TRUSTED_SENDERS_W).ToString();
Unfortunately I'm getting an error message (translated to English) like 'Object doesn't have such property'. In production it would have to work with Outlook clients connected to Exchange 2007 mailboxes.
Ok found it. The actual property is called PidTagExtendedRuleMessageCondition and the Blob format is described here MS-OXCSPAM and in MS-OXORULE respectively.

Get MailItem Recipient using Redemption.ISafeMailItem object

I am writing simple Outlook program in C# which records MailItem’s Recipients for sent mail. To build that I am hooking into Outlook Mailitem Send event to get Recipient collection. Also to avoid Outlook security prompt I am using Redemption SafeMailItem.
For reading Recipient collection I am assigning MailItem to SafeMailItem and read Recipients. However Recipient collection won’t be same if MailItem has unsaved changes. In order to copy Recipient collection, MailItem requires to be saved and then access via Redemption SafeMailItem.
Here is example.
//event handler
void _MailItemSend(ref bool Cancel)
{
SafeMailItem safeMailItem = (SafeMailItem)Activator.CreateInstance(Type.GetTypeFromProgID(RDOCustomClasses.SafeMailItem));
SafeRecipients recipients = null;
safeMailItem.Item = mailItem; // Assigning original mailItem which getting sent by outlook without saving it (just compose & send email before it get autosaved by outlook or manually)
recipients = safeMailItem.Recipients
// If mailItem have unsaved changes safeMailItem.Recipients will be different.
recipients.Count != mailItem.Recipients.Count;
}
So I believe calling Save() makes sense but I am not changing anything and calling Save() is causing another issue. When I try to quit Outlook it says:
there are unsaved changes “ do you want to save change”.
I tried accessing directly Mailitem.Recipients (it has latest and unsaved recipient list before mail getting send) but it creates Outlook security prompt. If I used Redemption it requires call to save before accessing it which creates other issue.
Is there a better way to receive Outlook Sent Mail Recipients in safe manner without modification ? Your suggestion will be appreciated.

Resources