i've written an outlook add-in (2010/2007) that gets the current selected (opened) mailitem and creates a new mail item based on the current mailitem's subject, body and attachments. My problem is that if the signiture is an image attachment, i can't position it in the original position of the current mailitem. the image of the signiture is placed on the top of the mail window (the attachment field). i've tried messing around with the attachment position, trying to place it at the end of the body but no luck, plus i think it's not the right way of doing it as i can't be sure what position each image placed within an email thread with multipile replaies for example. what i'm trying to go for here, is making a button like a Reply or Forward button but without the extra text that goes in the body (like: time the message was sent, sender etc..).
this is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Tools.Ribbon;
using ForwardAsNewMail;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace ForwardAsNewMail
{
public partial class ForwardAsNewMail
{
private void ForwardAsNewMail_Load(object sender, RibbonUIEventArgs e)
{
}
private void btnNewMail_Click(object sender, RibbonControlEventArgs e)
{
Outlook.MailItem oldMailItem = GetMailItem(e);
Outlook.Application outlookApp = new Outlook.Application();
Outlook.MailItem newMailItem = (Outlook.MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
newMailItem.HTMLBody = oldMailItem.HTMLBody;
newMailItem.Subject = oldMailItem.Subject;
#region Attahment
// Get the count of Attachments
int attachCount = oldMailItem.Attachments.Count;
if (attachCount > 0)
{
// loop through each attachment
for (int idx = 1; idx <= attachCount; idx++)
{
string sysPath = System.IO.Path.GetTempPath();
if (!System.IO.Directory.Exists(sysPath + "~test"))
{
System.IO.Directory.CreateDirectory(sysPath + "~test");
}
// get attached file and save in temp folder
string strSourceFileName = sysPath + "~test\\" +
oldMailItem.Attachments[idx].FileName;
oldMailItem.Attachments[idx].SaveAsFile(strSourceFileName);
string strDisplayName = "Attachment";
int intPosition = 1;
int intAttachType = (int)Outlook.OlAttachmentType.olEmbeddeditem;
// Add the current attachment
newMailItem.Attachments.Add(strSourceFileName,
intAttachType, intPosition, strDisplayName);
}
}
#endregion
newMailItem.Display();
}
///
/// Gets the mail item selected in the explorer view if one is selected or instance if that is the view active.
///
/// The instance containing the event data.
/// A Outlook.MailItem for the mail being viewed.
private Microsoft.Office.Interop.Outlook.MailItem GetMailItem(RibbonControlEventArgs e)
{
// Check to see if a item is select in explorer or we are in inspector.
if (e.Control.Context is Microsoft.Office.Interop.Outlook.Inspector)
{
Microsoft.Office.Interop.Outlook.Inspector inspector = (Microsoft.Office.Interop.Outlook.Inspector)e.Control.Context;
if (inspector.CurrentItem is Microsoft.Office.Interop.Outlook.MailItem)
{
return inspector.CurrentItem as Microsoft.Office.Interop.Outlook.MailItem;
}
}
if (e.Control.Context is Microsoft.Office.Interop.Outlook.Explorer)
{
Microsoft.Office.Interop.Outlook.Explorer explorer = (Microsoft.Office.Interop.Outlook.Explorer)e.Control.Context;
Microsoft.Office.Interop.Outlook.Selection selectedItems = explorer.Selection;
if (selectedItems.Count != 1)
{
return null;
}
if (selectedItems[1] is Microsoft.Office.Interop.Outlook.MailItem)
{
return selectedItems[1] as Microsoft.Office.Interop.Outlook.MailItem;
}
}
return null;
}
}
}
thanks in advance! :)
** EDIT With Solution** Well, after Dmitry pointed me out to the right direction I managed to find out how to save all attachment and embed the ones who were embedded. I also added an IF statement that checks if the attachment is embedded. so here is the code if any one interested:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Tools.Ribbon;
using ForwardAsNewMail;
using Outlook = Microsoft.Office.Interop.Outlook;
using System.Reflection;
namespace ForwardAsNewMail
{
public partial class ForwardAsNewMail
{
private void ForwardAsNewMail_Load(object sender, RibbonUIEventArgs e)
{
}
private void btnNewMail_Click(object sender, RibbonControlEventArgs e)
{
Outlook.MailItem oldMailItem = GetMailItem(e);
Outlook.Application outlookApp = new Outlook.Application();
Outlook.MailItem newMailItem = (Outlook.MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
newMailItem.HTMLBody = oldMailItem.HTMLBody;
newMailItem.Subject = oldMailItem.Subject;
#region Attahment
// Get the count of Attachments
int attachCount = oldMailItem.Attachments.Count;
if (attachCount > 0)
{
// loop through each attachment
for (int idx = 1; idx <= attachCount; idx++)
{
string sysPath = System.IO.Path.GetTempPath();
if (!System.IO.Directory.Exists(sysPath + "~test"))
{
System.IO.Directory.CreateDirectory(sysPath + "~test");
}
// determain if the attachment is embeded or not (in-line or not)
string atchPropValue = oldMailItem.Attachments[idx].PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001E");
if (atchPropValue == null || atchPropValue == string.Empty)
{
// get attached file and save in temp folder
string strSourceFileName = sysPath + "~test\\" + oldMailItem.Attachments[idx].FileName;
oldMailItem.Attachments[idx].SaveAsFile(strSourceFileName); // x
string strDisplayName = "Attachment";
int intPosition = oldMailItem.Attachments[idx].Index;
int intAttachType = (int)Outlook.OlAttachmentType.olEmbeddeditem;
// Add the current attachment
newMailItem.Attachments.Add(strSourceFileName, intAttachType, intPosition, strDisplayName);
}
else
{
Outlook.Attachment oldAttach = oldMailItem.Attachments[idx];
string strSourceFileName = sysPath + "~test\\" + oldAttach.FileName;
oldAttach.SaveAsFile(strSourceFileName);
// Add the current attachment
Outlook.Attachment newAttach = newMailItem.Attachments.Add(strSourceFileName,Missing.Value, Missing.Value, Missing.Value); // z
try
{
newAttach.PropertyAccessor.SetProperty(
@"http://schemas.microsoft.com/mapi/proptag/0x3712001F",
oldAttach.PropertyAccessor.GetProperty(
@"http://schemas.microsoft.com/mapi/proptag/0x3712001F"));
}
catch
{
}
}
}
}
#endregion
newMailItem.Display();
}
///
/// Gets the mail item selected in the explorer view if one is selected or instance if that is the view active.
///
/// The instance containing the event data.
/// A Outlook.MailItem for the mail being viewed.
private Microsoft.Office.Interop.Outlook.MailItem GetMailItem(RibbonControlEventArgs e)
{
// Check to see if a item is select in explorer or we are in inspector.
if (e.Control.Context is Microsoft.Office.Interop.Outlook.Inspector)
{
Microsoft.Office.Interop.Outlook.Inspector inspector = (Microsoft.Office.Interop.Outlook.Inspector)e.Control.Context;
if (inspector.CurrentItem is Microsoft.Office.Interop.Outlook.MailItem)
{
return inspector.CurrentItem as Microsoft.Office.Interop.Outlook.MailItem;
}
}
if (e.Control.Context is Microsoft.Office.Interop.Outlook.Explorer)
{
Microsoft.Office.Interop.Outlook.Explorer explorer = (Microsoft.Office.Interop.Outlook.Explorer)e.Control.Context;
Microsoft.Office.Interop.Outlook.Selection selectedItems = explorer.Selection;
if (selectedItems.Count != 1)
{
return null;
}
if (selectedItems[1] is Microsoft.Office.Interop.Outlook.MailItem)
{
return selectedItems[1] as Microsoft.Office.Interop.Outlook.MailItem;
}
}
return null;
}
}
}