Is there an easy way to programatically create a reply message in a VSTO Outlook addin that includes the original message, with the same look that occurs when clicking on the built-in reply button in Outlook? Or does one need to write code to retrieve the original email properties & text, and format it such that it looks as if the reply was composed by Outlook?
How about:
using System.Runtime.InteropServices;
using Outlook = Microsoft.Office.Interop.Outlook;
private void Reply(Outlook._MailItem mailItem)
{
Outlook.Actions actions = mailItem.Actions;
Outlook.Action action = actions["Reply"];
Marshal.ReleaseComObject(actions);
action.ReplyStyle = Outlook.OlActionReplyStyle.olIncludeOriginalText;
Outlook._MailItem response = action.Execute() as Outlook.MailItem;
Marshal.ReleaseComObject(action);
response.Display();
Marshal.ReleaseComObject(response);
}
Related
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.
I've a problem with my VSTO application for Outlook. I want to process the email body from a selected e-mail.
For selected e-mails out of the "default" list this code works fine:
Object selItem = Globals.ThisAddIn.Application.ActiveExplorer().Selection[1];
Outlook.MailItem mailItem = (Outlook.MailItem)selItem;
return mailItem.Body;
But if a user opens an email from the list with a double click, the email is displayed in a new window. If the addin is executed in this window (over the ribbon), the email from the list is still used (which is now in the background).
Is there a way to find out if the plugin was started in a separate window and then get the email body from it?
Regards,
Florian
Coincidentally, I just dealt with something similar to this. My situation isn't identical, but since I could easily piece together what it seems like you're looking for see below. I haven't tested this, and obviously you'll have to handle passing the correct reference to your Outlook Application, but since i had this immediately available I figured it would pass it along with the hope that you'll find it helpful.
private static void ribbonButton_Click(object sender, RibbonControlEventArgs e)
{
Outlook.Application application = new Outlook.Application();
Outlook.Inspector inspector = application.ActiveInspector();
if (application.ActiveExplorer().Selection[1] is Outlook.MailItem explorerMailItem)
{
// Write code to handle message if sourced from explorer (i.e., Reading Pane)
}
else if (inspector.CurrentItem is Outlook.MailItem inspectorMailItem)
{
// Write code to hanlde message if sourced from inspector
// (i.e., openened (double-clicked) message
}
}
When you double click on email item you open an inspector window and you can access it by using Application.ActiveInspector() method. The Inspector object has CurrentItem property which represents the opened item.
Also, you should avoid using multiple dots in expressions and properly release COM objects.
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.
I am writing an Outlook 2010/2013 plugin with C#. My abridged code looks like this:
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Application.ItemSend += Application_ItemSend;
}
void Application_ItemSend(object Item, ref bool Cancel)
{
Outlook.MailItem mailItem = Item as Outlook.MailItem;
// Scan for keywords before the user sends the email.
}
}
When the user hits the Send button on an email, the Application_ItemSend event handler executes. At that point, I want to scan the message body for certain keywords. However, I want to exclude older/original messages in that scan. I only want to scan the message that the user has just typed... mailItem.Body and mailItem.HTMLBody contain not only the message that the user is sending, but they also include all the previous messages in the entire thread/conversation. How can I filter those out?
I've not tested this myself yet, but this is on my todo list for our Addin as well. I haven't been able to find much documentation on this, but the OOXML of the mail (as well as the HTML) - at least in 2013 - contain something like the following:
OOXML:
<w:bookmarkStart w:id="0" w:name="_MailOriginal"/>
HTML:
<span style='mso-bookmark:_MailOriginal'>
This bookmark should allow you to find the point where you can cut off the message - as far as I know there is no other option in the API.
See here on how to get the OOXML of the mail:
Word.Document document = mailItem.GetInspector.WordEditor;
string xml = document.WordOpenXML;
I have written some code in c# that creates an ical file and attaches the file to an Outlook email. Is there a way to create an appointment that appears directly in Outlook calendar as accepted instead of a user having to open the attachment and accept it?
Thank you for help.
If you're talking about sending an appointment to someone else and getting it added to their calendar, I'm pretty sure that's not possible. At least, I hope that's not possible.
If you're talking about adding an appointment to your own calendar, you can use the Outlook automation objects for this. Add a reference to the Microsoft Outlook Object Library, and then do something like this:
using System;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Outlook.Application ol= new Outlook.Application();
Outlook.AppointmentItem cal = ol.CreateItem(Outlook.OlItemType.olAppointmentItem);
cal.Start = DateTime.Now;
cal.End = DateTime.Now.AddMinutes(30);
cal.Subject = "Test";
cal.Save();
}
}
}