C# VSTO Outlook - select multiple items and send them as attachment - c#

How do I select multiple items and open new mail form and add all selected items as attachments to the new email so I can send them together with the new email?
I guess, this could be broken into:
how to get multiple selected items in outlook (say user selects them all while holding Ctrl key to do multiple selection)?
How to open New Email form in Outlook?
How to attach selected item in 1 above and add them to the new email as attachments?
UPDATE:
So far I have managed to do following (Thanks to Dmitry's comment):
public void SendSelectedMailsAsAttachment()
{
try
{
Selection olSelection = HostAddIn.ActiveExplorer.Selection;
var count = olSelection.Count;
var items = new List<IItem>();
Microsoft.Office.Interop.Outlook.MailItem oMailItem = HostAddIn.Application.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
oMailItem.BodyFormat = Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatHTML;
foreach (var sel in olSelection)
{
oMailItem.Attachments.Add(sel);
}
oMailItem.Display(false);
}
catch (Exception ex)
{
//ex message
}
}
but with this code, following happens:
if I select single email and try to send it as attachment, the code above executes just fine and new email form opens but it will show no attachment.
if I select multiple emails and try to send them as attachment, the code above will throw exception when calling oMailItem.Attachments.Add(sel) for the 2nd time with exception "This operation is not supported until the entire message is downloaded. Download the message and try again."

Application.ActiveExplorer.Selection collection
Application.CreateItem / MailItem.Display
Loop through the items in the Application.ActiveExplorer.Selection collection and call MailItem.Attachments.Add for each item.

Related

Attempting to show message box and remove CC/To contents when writing new email

Hello and thank you in advance for any help you might be able to offer!
I am looking to create a C# add-in for Outlook that will take new emails that are being written and remove the contents of the To: and CC: fields if either exceeds a count of 10 recipients, then display a message box if either has exceeded 10. I've got some code already but I haven't worked with C# in about 7 years, so I'm very rusty and I feel like I might have done something wrong here. I'd greatly appreciate any insight on how to accomplish my goal.
The code:
private bool CheckRecipients(Outlook.MailItem mail)
{
bool retValue = false;
Outlook.Recipients recipients = null;
Outlook.Recipient recipientTo = null;
Outlook.Recipient recipientCC = null;
try
{
recipientTo = mail.recipientTo;
recipientCC = mail.recipientCC;
while(recipientTo.Count > 10)
{
recipientTo.Remove(1);
MessageBox.Show("You have added more than 10 recipients in the To: field. Please limit the To: field to 10 recipients.");
}
while(recipientCC.Count > 10)
{
recipientCC.Remove(1);
MessageBox.Show("You have added more than 10 recipients in the CC: field. Please limit the CC: field to 10 recipients.");
}
retValue = "something here";
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
finally
{
if (recipientCC != null) Marshal.ReleaseComObject(recipientCC);
if (recipientTo != null) Marshal.ReleaseComObject(recipientTo);
if (recipients != null) Marshal.ReleaseComObject(recipients);
}
return retValue;
}
After writing the code above, I ran the code as an add-in. Nothing happened.
There is no recipientTo and recipientCC properties in the Outlook object model:
recipientTo = mail.recipientTo;
recipientCC = mail.recipientCC;
Most probably the Recipients property is meant. It returns a Recipients collection that represents all the recipients for the Outlook item. Use Recipients(index) where index is the name or index number to return a single Recipient object. The name can be a string representing the display name, the alias, or the full SMTP email address of the recipient.
The Type property of a new Recipient object is set to the default for the associated AppointmentItem, JournalItem, MailItem, or TaskItem object and must be reset to indicate another recipient type. In case of MailItem recipient - one of the following OlMailRecipientType constants: olBCC, olCC, olOriginator, or olTo.
So, you can iterate over all recipients in the code where you could check the Type property and count recipients in each category if required.
You may find the article which I wrote for the technical blog helpful, see How To: Fill TO,CC and BCC fields in Outlook programmatically.
Another approach is to use a string based properties like To, Cc or Bcc that returns or sets a semicolon-delimited string list of display names for the recipients of the Outlook item. These properties contain the display names only, not the actual email addresses.
I am not sure if you can even compile your code - MailItem object does not implement recipientTo or recipientCC properties. It only exposes MailItem.Recipients collection. You can build your own To/CC lists by looping through the MailItem.Recipients collection and checking the Recipient.Type property (olTo/olCC/olBCC) for each recipient entry.

Send multiple attachments with Outlook, success but failiure

The following code is ment to create an e-mail and attach the one or multiple attachemnts. So far the code does just that with success, but it also creates the equal amount of e-mails with the right amount of attachments in each of them. I.e. with three attachments it creates three e-mails all with the three attachments in each of them.
private void SendMail(List<string> paths)
{
DateTime defDt = DateTime.Now.AddMinutes(3);
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MailItem mailItem = app.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
mailItem.BodyFormat = Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatHTML;
mailItem.GetInspector.Activate();
var signature = mailItem.HTMLBody;
mailItem.HTMLBody = signature;
foreach (string u in paths)
{
mailItem.Attachments.Add(u);
}
mailItem.DeferredDeliveryTime = defDt;
mailItem.Display(mailItem);
}
Why does it behave like this? There are no foreach loop besides the one for adding the multiple attachments. When firing with one attachment the error doesn't show (probably since it i creating just one e-mail with one attachment as excpected). Any thoughts from this great community?
The code was called in a foreach loop earlier in the code. The code presented works as expected.

how to automatically trigger a link in outlook email using VSTO

I'm trying to programmatically click on a link which creates an email with predefined subject,to,cc,bcc and body content of the email.My requirement is, If I select an Outlook mail item and click on “Approve via mail” in my Addin, the code will search for hyperlink “Click here to Approve” in the mail body and Automatically click on the hyperlink.
The hyperlink “Click here to Approve” creates an email with predefined subject,to,cc,bcc and body content of the email.
I'm not sure how to do it with VSTO as all the other solutions suggest using JQuery and Javascript
Object selObject = this.Application.ActiveExplorer().Selection[1];
Outlook._MailItem eMail = (Outlook._MailItem)
this.Application.CreateItem(Outlook.OlItemType.olMailItem);
eMail = ((Outlook._MailItem)selObject);
if(eMail.HTMLBody.Contains("Approve"))
{
}
I'm not sure what I can write in the IF segment of the code.Please Suggest.
Outlook doesn't provide anything for opening hyperlinks. You can use the the following code (Process.Start) for opening them in the default web browser:
Process.Start("your_hyperlink");
Or just create a Mail item progrmmatically in Outlook based on the info where the Approve button was clicked.
Outlook.MailItem mail = null;
Outlook.Recipients mailRecipients = null;
Outlook.Recipient mailRecipient = null;
try
{
mail = OutlookApp.CreateItem(Outlook.OlItemType.olMailItem)
as Outlook.MailItem;
mail.Subject = "A programatically generated e-mail";
mailRecipients = mail.Recipients;
mailRecipient = mailRecipients.Add("Eugene Astafiev");
mailRecipient.Resolve();
if (mailRecipient.Resolved)
{
mail.Send();
}
else
{
System.Windows.Forms.MessageBox.Show(
"There is no such record in your address book.");
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message,
"An exception is occured in the code of add-in.");
}
finally
{
if (mailRecipient != null) Marshal.ReleaseComObject(mailRecipient);
if (mailRecipients != null) Marshal.ReleaseComObject(mailRecipients);
if (mail != null) Marshal.ReleaseComObject(mail);
}
Take a look at the following articles for more information and samples:
How to create and show a new Outlook mail item programmatically: C#, VB.NET
How To: Create and send an Outlook message programmatically
How To: Fill TO,CC and BCC fields in Outlook programmatically
How To: Create a new Outlook message based on a template

Use attachments from calendar items - Outlook - C#

I'm trying to use the attachments included in calendar items pulled progmatically.
I have a list of chosen calendar subject lines from a previous dialog box, and while the subject is transferring properly, the body isn't working well (another question altogether) but the attachments aren't working whatsoever.
Here's my foreach loop where the attachments are being placed into an Attachments array for use later:
string[] subjects = new string[dialog.chosen.Count];
string[] bodies = new string[dialog.chosen.Count];
Attachments[] attach = new Attachments[dialog.chosen.Count];
foreach (Outlook.AppointmentItem appt in rangeAppts)
{
foreach (string text in dialog.chosen)
{
if (text == appt.Subject)
{
subjects[i] = appt.Subject;
bodies[i] = Convert.ToString(appt.Body);
attach[i] = appt.Attachments;
i = i + 1;
}
}
}
And then here's where I actually call the method:
sendEmailTemplate(bodies[i], subject, to, "", attachment: attach[i]);
And then the method itself:
public void sendEmailTemplate(string body, string subject, string to, string cc , Attachments attachment = null)
{
Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook._MailItem oMailItem = (Microsoft.Office.Interop.Outlook._MailItem)oApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
oMailItem.HTMLBody = body;
oMailItem.Subject = subject;
try
{
oMailItem.Attachments.Add(attachment);
}
catch {}
oMailItem.To = to;
oMailItem.CC = cc;
oMailItem.Display(false);
oMailItem.Application.ActiveInspector().WindowState = Microsoft.Office.Interop.Outlook.OlWindowState.olNormalWindow;
}
I've tried several things, however when I actually go to send the e-mail, I end up getting:
Exception: Member not found. HRESULT: 0x80020003
And then I haven't been able to get anything else to work. The try/catch loop on the method is to prevent the above exception as I was getting that exception regardless of whether or not an attachment was present, and now attachments just aren't being added.
I'm using Interop that comes with Office along with C#. Winforms if that makes a difference.
MailItem.Attachments takes either a string (fully qualified file name), or another Outlook item (MailItem, ContactItem, etc.).
You cannot pass Attachments object as an argument. If you need to copy the attachments, loop through all attachments in the Attachments collection, call Attachment.SaveAsFile for each attachment, pass the file name to MailItem.Attachments.Add, delete thee temporary file.

Get only text of Item from ItemAttachment (EWS Managed API)

Is there a way to remove HTML tags from Item which is from ItemAttachment?
I can get only text from Item. But not from Item which is from ItemAttachment.
Here is my code:
foreach (ItemAttachment itemAttach in item.Attachments.OfType<ItemAttachment>())
{
Console.WriteLine(itemAttach.Name);
itemAttach.Load();
PropertySet propSet = new PropertySet();
propSet.RequestedBodyType = BodyType.Text;
propSet.BasePropertySet = BasePropertySet.FirstClassProperties;
itemAttach.Item.Load(propSet);
Console.WriteLine(itemAttach.Item.Body.Text);
}
It will get this exception
This operation isn't supported on attachments
I tried binding to the exchange service with item ID.
It also gives me some exception!
Please give some advice on how I can do.
Jin,
The exception you are getting has to do with the property set you are creating. I don't see your code for getting the items so I can't determine the exact cause. I was able to get the following code to work on my machine. You should be able to modify it for your needs.
// Return the first ten items.
ItemView view = new ItemView(10);
// Set the query string to only find emails with attachments.
string querystring = "HasAttachments:true Kind:email";
// Find the items in the Inbox.
FindItemsResults<Item> results = service.FindItems(WellKnownFolderName.Inbox, querystring, view);
// Loop through the results.
foreach (EmailMessage email in results)
{
// Load the email message with the attachments
email.Load(new PropertySet(EmailMessageSchema.Attachments));
// Loop through the attachments.
foreach (Attachment attachment in email.Attachments)
{
// Only process item attachments.
if (attachment is ItemAttachment)
{
ItemAttachment itemAttachment = attachment as ItemAttachment;
// Load the attachment.
itemAttachment.Load(new PropertySet(EmailMessageSchema.TextBody));
// Output the body.
Console.WriteLine(itemAttachment.Item.TextBody);
}
}
For each email that had an item attachment I was able to see the body of the item with the HTML tags removed.
I hope this helps. If this solves your problem, please mark this post as answered.
Thanks,
--- Bob ---

Categories