This question already has an answer here:
Event Handler not being added to new Mail Items
(1 answer)
Closed 5 years ago.
I try to get the attachement file in an outlook plugin before the file attache to a the mailItem.
private void Inspectors_NewInspector(Outlook.Inspector Inspector)
{
if (Inspector.CurrentItem is Outlook.MailItem)
{
Outlook.MailItem mail = (Outlook.MailItem)Inspector.CurrentItem;
Inspector.AttachmentSelectionChange += Inspector_AttachmentSelectionChange;
Application.AttachmentContextMenuDisplay += Application_AttachmentContextMenuDisplay;
mail.BeforeAttachmentAdd += Mail_BeforeAttachmentAdd;
mail.AttachmentAdd += Mail_AttachmentAdd;
mail.BeforeAttachmentWriteToTempFile += Mail_BeforeAttachmentWriteToTempFile;
mail.BeforeAttachmentSave += Mail_BeforeAttachmentSave;
}}
When i create a new Email in outlook, my code passe by this method, but the event is never fired when i add an attachement to my email.
Any idea ?
You need to declare the source object at the class level (global scope) to prevent it from dwiping by the garbage collector, for example:
Outlook.MailItem mail = null;
Outlook.Inspector inspector = null;
private void Inspectors_NewInspector(Outlook.Inspector Inspector)
{
inspector = Inspector;
object oMail = inspector.CurrentItem;
if (oMail is Outlook.MailItem)
{
mail = (Outlook.MailItem)oMail.CurrentItem;
inspector.AttachmentSelectionChange += Inspector_AttachmentSelectionChange;
Application.AttachmentContextMenuDisplay += Application_AttachmentContextMenuDisplay;
mail.BeforeAttachmentAdd += Mail_BeforeAttachmentAdd;
mail.AttachmentAdd += Mail_AttachmentAdd;
mail.BeforeAttachmentWriteToTempFile += Mail_BeforeAttachmentWriteToTempFile;
mail.BeforeAttachmentSave += Mail_BeforeAttachmentSave;
}
}
Related
I plan to retrieve the mail item of the selected email on every chance of selected outlook email, but the event handle only gets triggered on startup, and sometimes properly. I can't seem to find what's causing the issue, most forums leads to a dead end, hence this post.
Anyway, here's a snippet of my Startup method:
private void Main_Startup(object sender, System.EventArgs e)
{
this.Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
Outlook.Explorer currentExplorer = this.Application.ActiveExplorer();
currentExplorer.SelectionChange += new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(CurrentExplorer_Event);
outlookNameSpace = this.Application.GetNamespace("MAPI");
inbox = outlookNameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
items = inbox.Items;
items.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(items_ItemAdd);
}
and here's a snippet of my CurrentExplorer_Event method:
private void CurrentExplorer_Event()
{
newSelectedEmail = new Email();
Outlook.MAPIFolder selectedFolder = this.Application.ActiveExplorer().CurrentFolder;
try
{
if (this.Application.ActiveExplorer().Selection.Count > 0)
{
Object selObject = this.Application.ActiveExplorer().Selection[1];
if (selObject is Outlook.MailItem)
{
Outlook.MailItem mailItem = (selObject as Outlook.MailItem);
GetEmailInfoFromOutlookEmail(mailItem);
}
}
}
catch (Exception ex)
{
Operations.SaveLogToFile(LogType.Error, "Main - CurrentExplorer_Event", ex.Message, ex.StackTrace);
}
}
Any help is greatly appreciated. Thank you!
The variable raising the events (currentExplorer) is a local variable. As soon as it goes out of scope, it becomes eligible to be released by the Garbage Collector. As soon as that happens, no events are raised.
Move the declaration of that variable to the class level.
I am building a addin for Outlookto add custom signature in outlook email, when the user click on "Reply" button.
As soon as user click on reply button in explorer, a new inspector opens and i close the inspector with code (which s#cks). There may be a way to totally disable the reply inspector from opening.
private Microsoft.Office.Tools.CustomTaskPane CustomTaskPane;
UserDetail usr = null;
Outlook.Explorer currentExplorer = null;
Outlook.MailItem mailItem;
private Inspector replyInspector;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
currentExplorer = this.Application.ActiveExplorer();
currentExplorer.SelectionChange +=
new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(CurrentExplorer_Event);
}
private void CurrentExplorer_Event()
{
if (this.Application.ActiveExplorer().Selection.Count == 1
&& this.Application.ActiveExplorer().Selection[1] is Outlook.MailItem)
{
if (mailItem != null)
{
// when the reply button is clicked
((Outlook.ItemEvents_10_Event)mailItem).Reply -= new Outlook.ItemEvents_10_ReplyEventHandler(MailItem_Reply);
// When an item is selected
Outlook.Selection mySelection = this.Application.ActiveExplorer().Selection;
Outlook.MailItem mailitem = null;
foreach (Object obj in mySelection)
{
if (obj is Outlook.MailItem)
{
mailitem = (Outlook.MailItem)obj;
if (mailitem != null)
{
if (mailitem.Sent)
{
else
{
// Compose
}
}
}
}
}
mailItem = this.Application.ActiveExplorer().Selection[1];
((Outlook.ItemEvents_10_Event)mailItem).Reply += new
Outlook.ItemEvents_10_ReplyEventHandler(MailItem_Reply);
// Close Inspector
replyInspector.Close(OlInspectorClose.olDiscard);
}
else
{
}
}
void MailItem_Reply(Object response, ref bool cancel)
{
try
{
MailItem mitem = (Outlook.MailItem)response;
replyInspector = (mitem).GetInspector;
replyInspector.Activate();
(mitem).HTMLBody = tempSignature + ((Outlook.MailItem)response).HTMLBody;
}
catch (System.Exception e)
{
MessageBox.Show(e.ToString());
}
}
Firstly, why would you want to close the inspector if you are opening it anyway? Why not insert the signature when the inspector is opened?
Secondly, you cannot concatenate two HTML strings and expect the resulting string to be valid HTML, The two needs to be merged. Or, better yet, use Word Object Model (Word.Document is returned from Inspector.WordEditor) to insert any text anywhere in the message body.
I'm trying to create an Outlook add-in that processes a certain MailItem and forwards the result on to another group of people. In order to do the processing, I believe I need to use the WordEditor in order to get the proper formatting, but when I try to access that object, it returns null. I'm able to send the mail properly when I don't access the WordEditor, so it's probably something simple I've overlooked. How can I access the WordEditor for this new MailItem?
Outlook.NameSpace outlookNameSpace;
Outlook.MAPIFolder inbox;
Outlook.Items items;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
outlookNameSpace = this.Application.GetNamespace("MAPI");
inbox = outlookNameSpace.GetDefaultFolder(
Microsoft.Office.Interop.Outlook.
OlDefaultFolders.olFolderInbox);
items = inbox.Items;
items.ItemAdd +=
new Outlook.ItemsEvents_ItemAddEventHandler(items_ItemAdd);
}
void items_ItemAdd(object Item)
{
string filter = "Filter";
if (Item is Outlook.MailItem)
{
Outlook.MailItem mail = (Outlook.MailItem)Item;
if (Item != null)
{
if (mail.MessageClass == "IPM.Note" &&
mail.Subject.ToUpper().Contains(filter.ToUpper())
&& mail.Attachments.Count == 1)
{
Outlook.Attachments attachments = mail.Attachments;
if (attachments != null)
{
Outlook.Attachment file = attachments[1];
//Process attachment...
Outlook.MailItem newMail = this.Application.CreateItem(Outlook.OlItemType.olMailItem);
Outlook.Inspector insp = newMail.GetInspector;
insp.Activate();
newMail.Subject = "Subject";
newMail.To = "email#example.com";
Word.Document emailBody = insp.WordEditor as Word.Document;
//emailBody is always null
newMail.Send();
System.Runtime.InteropServices.Marshal.ReleaseComObject(newMail);
System.Runtime.InteropServices.Marshal.ReleaseComObject(file);
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(attachments);
}
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(mail);
}
}
Set the MailIten.HTMLBody appropriately without using the Inspector object and the Word Object Model.
I am creating a outlook 2013 add-on with C# and Visual Studio 2012 and I want to get the attachment file from the current (open) mail window when a button clicked and save it to a local directory.
Is there any example for this action?
Thank you.
First you would need to get the object of the current mail item. After that you can just loop through the .Attachments of the mail item and save them with .SaveAsFile(filePath).
var _thisApp = this.Application;
Outlook.MailItem _email;
// Get current email
if(_thisApp.ActiveWindow() is Outlook.Inspector)
{
Outlook.Inspector insp = _thisApp.ActiveWindow() as Outlook.Inspector;
_email = insp.CurrentItem as Outlook.MailItem;
}
else if(_thisApp.AcitveWindow() is Outlook.Explorer)
{
Outlook.Explorer exp = _thisApp.ActiveExplorer();
if(exp.Selection.Count > 0)
_email = exp.Selection[1] as Outlook.MailItem;
}
// Loop through the attachments
foreach(Outlook.Attachment attachment in _email.Attachments)
{
// Some other stuff
string filePath = #"C:\Saved Attachments\" + attachment.FileName;
attachment.SaveAsFile(filePath);
}
EDIT: Sample to retrieve this.Application
private Outlook.Application _thisApp;
private Outlook.Inspectors _inspectors;
// Function in ThisAddin.cs
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
_thisApp = this.Application;
_inspectors = _thisApp.Inspectors;
_inspectors.NewInspector +=
new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);
}
I'm going to access Outlook MAPI folder and get mail address.Here is my method
public static string GetSenderEmailAddress(Microsoft.Office.Interop.Outlook.MailItem mapiObject)
{
Microsoft.Office.Interop.Outlook.PropertyAccessor oPA;
string propName = "http://schemas.microsoft.com/mapi/proptag/0x0065001F";
oPA = mapiObject.PropertyAccessor;
string email = oPA.GetProperty(propName).ToString();
return email;
}
When button click event called,i need to fire that method and retrieve mail address.
Button click event is here.
private void button3_Click(object sender, RibbonControlEventArgs e)
{
string mailadd = ThisAddIn.GetSenderEmailAddress(Microsoft.Office.Interop.Outlook.MailItem);
System.Windows.Forms.MessageBox.Show(mailadd);
}
Error goes here
Microsoft.Office.Interop.Outlook.MailItem is a 'type'which is not valid in the given context
This is my first addin,Does anyone know how to achieve this result?
You can use the RibbonControlEventArgs to access the Context which will provide you the MailItem instance.
private Outlook.MailItem GetMailItem(RibbonControlEventArgs e)
{
// Inspector Window
if (e.Control.Context is Outlook.Inspector)
{
Outlook.Inspector inspector = e.Control.Context as Outlook.Inspector;
if (inspector == null) return null;
if (inspector.CurrentItem is Outlook.MailItem)
return inspector.CurrentItem as Outlook.MailItem;
}
// Explorer Window
if (e.Control.Context is Outlook.Explorer)
{
Outlook.Explorer explorer = e.Control.Context as Outlook.Explorer;
if (explorer == null) return null;
Outlook.Selection selectedItems = explorer.Selection;
if (selectedItems.Count != 1) return null;
if (selectedItems[1] is Outlook.MailItem)
return selectedItems[1] as Outlook.MailItem;
}
return null;
}
You can add this method and then make use of it like so...
string mailAddress = string.Empty;
Outlook.MailItem mailItem = GetMailItem(e);
if (mailItem != null)
mailAddress = ThisAddIn.GetSenderEmailAddress(mailItem);