I am working on the following code to determine the user's Name and show at the bottom of the email. The code is working perfectly, I just don't know how to get the name and put it on HtmlBody from another class.
Right now, it's showing the result in the Console.
public void GetCurrentUserInfo()
{
Outlook.AddressEntry addrEntry =
Application.Session.CurrentUser.AddressEntry;
if (addrEntry.Type == "EX")
{
Outlook.ExchangeUser currentUser =
Application.Session.CurrentUser.
AddressEntry.GetExchangeUser();
if (currentUser != null)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("Name: "
+ currentUser.Name);
Debug.WriteLine(sb.ToString());
}
}
I am close with this following code? Which feels so wrong!
mailitem.HTMLBody = "<html><body> </br><div class="Name", +sb.ToString()></br></body></html>";
The HTMLBody property value represents a well-formed HTML document. So, you need to find the closing </body> tag and insert your data before it. Use the InStr function available in VBA:
Sub FindWord()
Dim Position As Integer
Position = InStr(1, HTMLBody, "</body>", vbBinaryCompare)
MsgBox Position
End Sub
I am currently developing an add-in for Microsoft Outlook that adds an image right before the tag of an html body. This image is located on a remote server so the source of the image tag is http://someserver.com/image.jpg
This works exactly as expected on a fresh e-mail ( aka a new e-mail )
However when a user clicks reply, or forward for some reason the image source gets changed to cid:image001.jpg and the actual image source gets put in the alt tag.
I am altering the body on the send event as I want the image to be added after the e-mail is finished being written.
The code that is run at the send event
void OutlookApplication_ItemSend(object Item, ref bool Cancel)
{
if (Item is Outlook.MailItem)
{
Outlook.MailItem mailItem = (Outlook.MailItem)Item;
string image = "<img src='http://someserver.com/attach.jpg' width=\"100\" height=\"225\" alt=\"\" />";
string body = mailItem.HTMLBody;
body = body.Replace("</body>", image + "</body>");
mailItem.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
mailItem.HTMLBody = body;
}
}
So I found a way to do it that works. What I ended up having to do was create a new mailItem, copy the existing mailitem into it, modify and send that item and cancel the original. The following code shows how I did it:
void OutlookApplication_ItemSend(object Item, ref bool Cancel)
{
if (Item is Outlook.MailItem)
{
Outlook.Inspector currInspector;
currInspector = outlookApplication.ActiveInspector();
Outlook.MailItem oldMailItem = (Outlook.MailItem)Item;
Outlook.MailItem mailItem = oldMailItem.Copy();
string image = "<img src='http://someserver.com/attach.jpg' width=\"1\" height=\"1\" alt=\"\" />";
string body = mailItem.HTMLBody;
body = body.Replace("</body>", image+"</body>");
mailItem.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
mailItem.HTMLBody = body;
mailItem.Send();
Cancel = true;
currInspector.Close(Outlook.OlInspectorClose.olDiscard);
}
}
I'd recommend adding images inside the ... elements. You can read more about HTML rendering capabilities in the following series of articles:
Word 2007 HTML and CSS Rendering Capabilities in Outlook 2007 (Part 1 of 2)
Word 2007 HTML and CSS Rendering Capabilities in Outlook 2007 (Part 2 of 2)
Word is used as an email editor in latest Outlook versions.
Do you get any issue with the ItemSend event handler? Does it work?
I'm having a slight problem with adding text to forwarding emails. This is my current code:
private void ForwardFunction(Outlook.MailItem email)
{
Outlook.MailItem forwardEmail = ((Outlook._MailItem)email).Forward();
Outlook.Inspector forwardInsp = forwardEmail.GetInspector;
Word.Document forwardDoc = forwardInsp.WordEditor;
Word.Range forwardRange = forwardDoc.Range(0,1);
string forwardText = "This is some text";
forwardRange.Text = forwardText + forwardRange.text
newEmail.Recipients.Add("myemail");
forwardEmail.Save();
((Outlook._MailItem)forwardEmail).Send();
}
I've gone through it and it does add the text to the range, but when I receive the forwarded email it doesn't contain any of the additional text. I've used similar code to edit current emails that the user is editing (New, Replies/Forwards, InlineResponses) with success, but the email being passed to the function is the currently selected email in the inbox. Not sure if this matters, maybe because it's not being edited by the user.
I couldn't find a specific way to add new text to a programmatically forwarded email.
For anyone else interested in this, I ended up using the .HTMLBody. It seems that using the .GetInspector either gets the inspector of the _email instead of fEmail and you can't edit it or it gets the correct inspector but it can't edit it. Either way, using the .HTMLBody seems to get around it.
Outlook.MailItem fEmail = ((Outlook._MailItem)_email).Forward();
string forwardText;
forwardText = "class=MsoNormal>";
forwardText += "This is my forwarded message";
forwardText += "Bonus hyper link <a href='" + hyperlinkText + "'>" + hyperlinkText + "</a>";
var regex = new Regex(Regex.Escape("class=MsoNormal>"));
fEmail.HTMLBody = regex.Replace(fEmail.HTMLBody, forwardText, 1);
fEmail.Save();
fEmail.AutoForwarded = true;
((Outlook._MailItem)fEmail).Send();
I am trying to make a function that fetches the body of an email with a given search criteria. When I fetch items from the mailbox and try to get the body, it only writes part of the body. I want ALL text from the body instead. How can I do this? This is what I have so far:
Outlook.Application myApp = new Outlook.Application();
const string PR_HAS_ATTACH = "http://schemas.microsoft.com/mapi/proptag/0x0E1B000B";
// Obtain Inbox
Outlook.Folder folder = myApp.Session.GetDefaultFolder(OlDefaultFolders.olFolderInbox) as Microsoft.Office.Interop.Outlook.Folder;
Outlook.Table table = folder.GetTable(Microsoft.Office.Interop.Outlook.OlTableContents.olUserItems);
// Remove default columns
table.Columns.RemoveAll();
// Add using built-in name
table.Columns.Add("Subject");
table.Columns.Add("ReceivedTime");
table.Sort("ReceivedTime", Microsoft.Office.Interop.Outlook.OlSortOrder.olDescending);
// Add using namespace
// Date received
table.Columns.Add("urn:schemas:httpmail:textdescription");
while (!table.EndOfTable)
{
Outlook.Row row = table.GetNextRow();
if (row["Subject"].ToString().ToLower().Contains(subject.Text.ToLower()) && row["ReceivedTime"].ToString().Contains(cellCreationDate))
{
body.Text = row["urn:schemas:httpmail:textdescription"].ToString();
}
}
You can't use Outlook.Table and then urn:shcemas:httpmail.textdescription to get the entire body. textdescription only returns the first 255 characters of the body as noted here http://msdn.microsoft.com/en-us/library/office/ff861580.aspx.
here is an alternative.
// change this in your code
body.Text = row["urn:schemas:httpmail:textdescription"].ToString();
// To this
Microsoft.Office.Interop.Outlook.MailItem mailItem =
myApp.Session.GetItemFromID(row["EntryID"]);
body.Text = mailItem.Body;
If create the body property as
System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();
message.Body ="First Line \n second line";
I also tried
message.Body ="First Line" + system.environment + "second line";
Both of these were ignored when I received the message (using outlook).
Any ideas on how to get mutliple lines? I am trying to avoid html encoding so that the email will play nicer with spam filters.
thanks
As per the comment by drris, if IsBodyHtml is set to true then a standard newline could potentially be ignored by design, I know you mention avoiding HTML but try using <br /> instead, even if just to see if this 'solves' the problem - then you can rule out by what you know:
var message = new System.Net.Mail.MailMessage();
message.Body = "First Line <br /> second line";
You may also just try setting IsBodyHtml to false and determining if newlines work in that instance, although, unless you set it to true explicitly I'm pretty sure it defaults to false anyway.
Also as a side note, avoiding HTML in emails is not necessarily any aid in getting the message through spam filters, AFAIK - if anything, the most you do by this is ensure cross-mail-client compatibility in terms of layout. To 'play nice' with spam filters, a number of other things ought to be taken into account; even so much as the subject and content of the mail, who the mail is sent from and where and do they match et cetera. An email simply won't be discriminated against because it is marked up with HTML.
In case you dont need the message body in html, turn it off:
message.IsBodyHtml = false;
then use e.g:
message.Body = "First line" + Environment.NewLine +
"Second line";
but if you need to have it in html for some reason, use the html-tag:
message.Body = "First line <br /> Second line";
Beginning each new line with two white spaces will avoid the auto-remove perpetrated by Outlook.
var lineString = " line 1\r\n";
linestring += " line 2";
Will correctly display:
line 1
line 2
It's a little clumsy feeling to use, but it does the job without a lot of extra effort being spent on it.
I usually like a StringBuilder when I'm working with MailMessage. Adding new lines is easy (via the AppendLine method), and you can simply set the Message's Body equal to StringBuilder.ToString() (... for the instance of StringBuilder).
StringBuilder result = new StringBuilder("my content here...");
result.AppendLine(); // break line
You need to enable IsBodyHTML
message.IsBodyHtml = true; //This will enable using HTML elements in email body
message.Body ="First Line <br /> second line";
The key to this is when you said
using Outlook.
I have had the same problem with perfectly formatted text body e-mails. It's Outlook that make trash out of it. Occasionally it is kind enough to tell you that "extra line breaks were removed". Usually it just does what it wants and makes you look stupid.
So I put in a terse body and put my nice formatted text in an attachement. You can either do that or format the body in HTML.
Try this
IsBodyHtml = false,
BodyEncoding = Encoding.UTF8,
BodyTransferEncoding = System.Net.Mime.TransferEncoding.EightBit
If you wish to stick to using \r\n
I managed to get mine working after trying for one whole day!
Try using the verbatim operator "#" before your message:
message.Body =
#"
FirstLine
SecondLine
"
Consider that also the distance of the text from the left margin affects on the real distance from the email body left margin..
Try using a StringBuilder object and use the appendline method. That might work.
Sometimes you don't want to create a html e-mail.
I solved the problem this way :
Replace \n by \t\n
The tab will not be shown, but the newline will work.
Today I found the same issue on a Error reporting app. I don't want to resort to HTML, to allow outlook to display the messages I had to do (assuming StringBuilder sb):
sb.Append(" \r\n\r\n").Append("Exception Time:" + DateTime.UtcNow.ToString());
I realise this may have been answered before. However, i had this issue this morning with Environment.Newline not being preserved in the email body.
The following is a full (Now Working with Environment.NewLine being preserved) method i use for sending an email through my program.(The Modules.MessageUpdate portion can be skipped as this just writes to a log file i have.) This is located on the main page of my WinForms program.
private void MasterMail(string MailContents)
{
Modules.MessageUpdate(this, ObjApp, EH, 3, 25, "", "", "", 0, 0, 0, 0, "Master Email - MasterMail Called.", "N", MainTxtDict, MessageResourcesTxtDict);
Outlook.Application OApp = new Outlook.Application();
//Location of email template to use. Outlook wont include my Signature through this automation so template contains only that.
string Temp = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + ResourceDetails.DictionaryResources("SigTempEmail", MainTxtDict);
Outlook.Folder folder = OApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderDrafts) as Outlook.Folder;
//create the email object.
Outlook.MailItem TestEmail = OApp.CreateItemFromTemplate(Temp, folder) as Outlook.MailItem;
//Set subject line.
TestEmail.Subject = "Automation Results";
//Create Recipients object.
Outlook.Recipients oRecips = (Outlook.Recipients)TestEmail.Recipients;
//Set and check email addresses to send to.
Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add("EmailAddressToSendTo");
oRecip.Resolve();
//Set the body of the email. (.HTMLBody for HTML Emails. .Body will preserve "Environment.NewLine")
TestEmail.Body = MailContents + TestEmail.Body;
try
{
//If outlook is not open, Open it.
Process[] pName = Process.GetProcessesByName("OUTLOOK.EXE");
if (pName.Length == 0)
{
System.Diagnostics.Process.Start(#"C:\Program Files\Microsoft Office\root\Office16\OUTLOOK.EXE");
}
//Send email
TestEmail.Send();
//Update logfile - Success.
Modules.MessageUpdate(this, ObjApp, EH, 1, 17, "", "", "", 0, 0, 0, 0, "Master Email sent.", "Y", MainTxtDict, MessageResourcesTxtDict);
}
catch (Exception E)
{
//Update LogFile - Fail.
Modules.MessageUpdate(this, ObjApp, EH, 5, 4, "", "", "", 0, 0, 0, 0, "Master Email - Error Occurred. System says: " + E.Message, "Y", MainTxtDict, MessageResourcesTxtDict);
}
finally
{
if (OApp != null)
{
OApp = null;
}
if (folder != null)
{
folder = null;
}
if (TestEmail != null)
{
TestEmail = null;
}
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
You can add multiple recipients by either including a "; " between email addresses manually, or in one of my other methods i populate from a Txt file into a dictionary and use that to create the recipients email addresses using the following snippet.
foreach (KeyValuePair<string, string> kvp in EmailDict)
{
Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add(kvp.Value);
RecipientList += string.Format("{0}; ", kvp.Value);
oRecip.Resolve();
}
I hope at least some of this helps someone.
Adding . before \r\n makes it work if the original string before \r\n has no .
Other characters may work. I didn't try.
With or without the three lines including IsBodyHtml, not a matter.
Something that worked for me was simply separating data with a :
message.Body = FirstLine + ":" + SecondLine;
I hope this helps