Copying mail body to new mail in outlook by coding in c# - c#

In Outlook 2013, I want the content of the mail body in a new mail programmatically.
Below is my code:
void Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
{
Outlook.MailItem mailItem = Inspector.CurrentItem as Outlook.MailItem;
Outlook.Application oApp = new Outlook.Application();
Outlook.Explorer oExplorer = oApp.ActiveExplorer();
Outlook.Selection oSelection = oExplorer.Selection;
foreach (object item in oSelection)
{
Outlook.MailItem mi = (Outlook.MailItem)item;
mailItem.HTMLBody = mi.HTMLBody;
}
}
Everything works fine, but the image present in the original mail is not displayed. Instead it shows something like cid:image002.png.
Not sure what is the reason.
Also I want to give it to the client, so I can't save mail content locally.

If you see cid:image002.png statements in the HTML markup of the message body you need to attach embedded items to new emails as well.
The basic principle of adding an embedded image is to attach the image to the item and then using the HTMLBody to write HTML to add the attachment cid as a reference in the HTML.
Attachment attachment = newMail.Attachments.Add(
#"E:\Pictures\image001.jpg"
, OlAttachmentType.olEmbeddeditem
, null
, "Some image display name"
);
string imageCid = "image001.jpg#123";
attachment.PropertyAccessor.SetProperty(
"http://schemas.microsoft.com/mapi/proptag/0x3712001E"
, imageCid
);
newMail.HTMLBody = String.Format(
"<body><img src=\"cid:{0}\"></body>"
, imageCid
);
Be aware, you will need to save the file on disk and the re-attach it to the new email. The Add method of the Attachment class accepts a file (represented by the full file system path with a file name) or an Outlook item that constitutes the attachment.
Also I'd recommend avoiding the foreach loop in the code with OOM objects. Use the for loop instead. It allows to release underlying COM objects instantly. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. You can read more about that in the Systematically Releasing Objects article.

As i understand you want to copy the attachments from existing mailitem to new one... Then you can try this
foreach( var x in mailItem.Attachments)
{
mi.Attachments.Add(x);
}

Related

How to Open Outlook file attachment directly not saving it? ( with C# VSTO)

I need to open mail file attachment directly from mail. Let say I have .txt file. I have already attached it to my mail. But now I need to open it, change some words and save it (it is manual part). How can I do this? My code is:
private void button2_Click(object sender, EventArgs e)
{
Outlook.Inspector currInspector = null;
Outlook.MailItem mail = null;
Outlook.Attachments attachments = null;
currInspector = Globals.ThisAddIn.Application.ActiveInspector();
if (currInspector != null) {
mail = (Outlook.MailItem)currInspector.CurrentItem;
attachments = mail.Attachments;
attachments.Add(#"C:\install\CSharp\tulemus.txt", Outlook.OlAttachmentType.olByValue);
}
The Outlook object model doesn't provide any property or method for that. You can try to read the attached files from the cache folder maintained by Outlook. See Finding Outlook temporary folder for email attachments for more information.
Also, you can use a low-level API (Extended MAPI) where you can access the PR_ATTACH_DATA_BIN property, read more about the algorithm in the Opening an attachment article.
In addition to what Eugene suggested - use Attachment.PropertyAccessor or MAPI (C++ or Delphi) to access the PR_ATTACH_DATA_BIN property (DASL name "http://schemas.microsoft.com/mapi/proptag/0x37010102") - you can also use Redemption (I am its author): its RDOAttach.AsText / AsArray / AsStream properties allow to modify attachment contents on the fly

Get sub messages from Outlook .msg files

I need to parse a few .msg files which have trail mails. Is there any way to get the sub messages and identify the initiated and the responded emails.
I do not want to use any third party tools. I am allowed to use the Outlook interop.
Below is the code that I have used to read the msg file.I am able to get the Body ,HTMLBody and other details.But I actually need all the trailing messages.
outlook._Application app = null;
outlook.MailItem item = null;
outlook.NameSpace session = null;
try
{
app = new outlook.Application();
session = app.Session;
item = session.OpenSharedItem(file) as outlook.MailItem;
}
catch(Exception ex)
{ }
If you are limited to OOM only, the only way to do that is to save each embedded message attachment as an MSG file (Attachment.SaveAsFile), then open it using Namespace.OpenSharedItem.
If using Redemption (I am its author) is an option, an MSG file can be opened using RDOSession.GetMessageFromMsgFile (similar to Namespace.OpenSharedItem in OOM), and the embedded message attachment can be accessed using the RDOAttachment.EmbeddedMsg property (returns RDOMail object) - no need to save the attachment first.

Email.Body not updating after editing WordEditor

I have a form region for the reading pane. I retrieve the wordeditor for the forward mail item and then add info to the word document. This seems to work when I don't create and send the email in the same function, but when I want to create a forward email, edit it, and send it, the Email.Body doesn't update.
_email = this.OutlookItem as Outlook.MailItem;
private void SendForwardEmail()
{
Outlook.MailIem fEmail = null;
Word.Document doc = null;
try
{
fEmail = ((Outlook._MailItem)_email).Forward();
doc = GetWordEditor(fEmail);
EditDoc(doc);
var tmp = doc.Range().Text;
var tmp1 = fEmail.Body; // tmp1 won't have what I added to tmp
((Outlook._MailItem)fEmail).Send(); // This will send with the fEmail.Body value
// and won't show edits to the word doc
}
finally
{
Release(doc);
Release(fEmail);
}
}
I use similar code in a form region for composing emails, the difference is that by the time the Send event is triggered, the Email.Body has updated with the edits to the word doc. I've tried fEmail.Save(), but doesn't seem to work. The word editor does save the work because I can access the word editor at a different point and it will still have the edits. The Email.Body just doesn't update with the changes.
EDIT: I'll add that doing the following does update the Email.Body, but seems like a funky solution.
fEmail.Display();
((Outlook.MailItem)fEmail).Close(Outlook.OlInspectorClose.olSave);
Where and when do you run the code? Is it on a secondary thread?
Anyway, I'd suggest starting from releasing all underlying COM objects instantly. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook/Word object when you have finished using it. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about that in the Systematically Releasing Objects article.

Creating an rtf custom mail item

I'm using redemption to create a custom mail item and save it in the draft folder of my outlook. Currently the mailItem is saved in HTML format. I want to be able to save it in rtf Format. How can I do that ?
Here is the code I am using :
Redemption.RDOSession session = new Redemption.RDOSession();
session.MAPIOBJECT = olApp.Session.MAPIOBJECT;
Redemption.RDOFolder rFolder = session.GetDefaultFolder(Redemption.rdoDefaultFolders.olFolderDrafts);
Redemption.RDOMail rMsg = rFolder.Items.Add("ipm.note.mep");
// modify some custom fields ...
rMsg.BodyFormat = 3;
rMsg.Save();
Outlook.MailItem oMep = olApp.Session.GetItemFromID(rMsg.EntryID);
oMep.BodyFormat = Outlook.OlBodyFormat.olFormatRichText;
oMep.Display(false);
Changing the bodyFormat doesn't seem to work. I also tried the saveAs method with no success. I can change the format manually when the mailItem is open, but I want to do that automatically within my C# code.
Have you tried to set the RDOMail.RtfBody property?

Using CreateItemFromTemplate to process an olEmbeddeditem Outlook attachment

I am using C# to process a message in my Outlook inbox that contains attachments. One of the attachments is of type olEmbeddeditem. I need to be able to process the contents of that attachment. From what I can tell I need to save the attachment to disk and use CreateItemFromTemplate which would return an object.
The issue I have is that an olEmbeddeditem can be any of the Outlook object types MailItem, ContactItem, MeetingItem, etc. How do you know which object type a particular olEmbeddeditem attachment is going to be so that you know the object that will be returned by CreateItemFromTemplate?
Alternatively, if there is a better way to get olEmbeddeditem attachment contents into an object for processing I'd be open to that too.
I found the following code on Google Groups for determining the type of an Outlook object:
Type t = SomeOutlookObject.GetType();
string messageClass = t.InvokeMember("MessageClass",
BindingFlags.Public |
BindingFlags.GetField |
BindingFlags.GetProperty,
null,
SomeOutlookObject,
new object[]{}).ToString();
Console.WriteLine("\tType: " + messageClass);
I don't know if that helps with an olEmbedded item, but it seems to identify regular messages, calendar items, etc.
Working with email attachments that are also emails which in turn contains user defined properties that I want to access, then I perform the following steps:
Outlook.Application mailApplication = new Outlook.Application();
Outlook.NameSpace mailNameSpace = mailApplication.GetNamespace(“mapi”);
// make sure it is an embedded item
If(myAttachment.Type == Outlook.OlAttachmentType.olEmbeddeditem)
{
myAttachment.Type.SaveAsFile(“temp.msg”);
Outlook.MailItem attachedEmail = (Outlook.MailItem)mailNameSpace.OpenSharedItem(“temp.msg”);
String customProperty = attachedEmail.PropertyAccessor.GetProperty(
“http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-c000-000000000046}/myProp
}
If you open the MailItem using, then I will not have access to the properties as mentioned above:
Outlook.MailItem attachedEmail = (Outlook.MailItem)mailApplication.CreateFromTemplate(“temp.msg”);

Categories

Resources