Sending email from the specified Outlook Account - c#

I am using Outlook2013 which has a number of mailboxes from both exchange and pop servers.(Rob#mydomain.com[default exchange], rob#somethingdifferent.com[POP], support#mydomain.com[exchange])
I am trying to use Outlook automation to send an email using the support#mydomain.com account.
The problem I am having is the below code creates a mail item in the support outbox but the from field is rob#mydomain.com not support#mydomain.com. This stops it from being sent.
I would like to change the from address to support#mydomain.com. I thought that by setting the Sendusingaccount property did this.
Any help is greatly appreciated.
public static string Send_Email_Outlook(string _recipient, string _message, string _subject, string _cc, string _bcc, string accountname)
{
try
{
Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
// Get the NameSpace and Logon information.
Microsoft.Office.Interop.Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
// Log on by using a dialog box to choose the profile.
oNS.Logon(Missing.Value, Missing.Value, true, true);
// Create a new mail item.
Microsoft.Office.Interop.Outlook.MailItem oMsg = (Microsoft.Office.Interop.Outlook.MailItem)oApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
// Set the subject.
oMsg.Subject = _subject;
// Set HTMLBody.
oMsg.HTMLBody = _message;
oMsg.To = _recipient;
oMsg.CC = _cc;
oMsg.BCC = _bcc;
#region Send via another account
if (accountname.Trim().Length != 0)
{
Microsoft.Office.Interop.Outlook.Accounts accounts = oMsg.Session.Accounts;
for (int i = 1; i <= accounts.Count; i++)
{
string accountfound = accounts[i].DisplayName.ToLower();
if (accountname.ToLower() == accountfound)
{
oMsg.SendUsingAccount = accounts[i]; // Send using support account
Microsoft.Office.Interop.Outlook.Recipient recipient = oMsg.Session.CreateRecipient(accountfound);
oMsg.Sender = recipient.AddressEntry;
break;
}
}
}
#endregion
// Send.
(oMsg as Microsoft.Office.Interop.Outlook._MailItem).Send();
// Log off.
oNS.Logoff();
// Clean up.
//oRecip = null;
//oRecips = null;
oMsg = null;
oNS = null;
oApp = null;
}
// Return Error Message
catch (Exception e)
{
return e.Message;
}
// Default return value.
return "";
}

Yes, you can use the SendUsingAccount property to set up the correct account you need to send items from.
public static Outlook.Account GetAccountForEmailAddress(Outlook.Application application, string smtpAddress)
{
// Loop over the Accounts collection of the current Outlook session.
Outlook.Accounts accounts = application.Session.Accounts;
foreach (Outlook.Account account in accounts)
{
// When the e-mail address matches, return the account.
if (account.SmtpAddress == smtpAddress)
{
return account;
}
}
throw new System.Exception(string.Format("No Account with SmtpAddress: {0} exists!", smtpAddress));
}
public static string Send_Email_Outlook(string _recipient, string _message, string _subject, string _cc, string _bcc, string accountname)
{
try
{
Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
// Get the NameSpace and Logon information.
Microsoft.Office.Interop.Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
// Log on by using a dialog box to choose the profile.
oNS.Logon(Missing.Value, Missing.Value, true, true);
// Create a new mail item.
Microsoft.Office.Interop.Outlook.MailItem oMsg = (Microsoft.Office.Interop.Outlook.MailItem)oApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
// Set the subject.
oMsg.Subject = _subject;
// Set HTMLBody.
oMsg.HTMLBody = _message;
oMsg.To = _recipient;
oMsg.CC = _cc;
oMsg.BCC = _bcc;
#region Send via another account
// Retrieve the account that has the specific SMTP address.
Outlook.Account account = GetAccountForEmailAddress(oApp , "support#mydomain.com");
// Use this account to send the e-mail.
oMsg.SendUsingAccount = account;
// Send.
(oMsg as Microsoft.Office.Interop.Outlook._MailItem).Send();
// Log off.
oNS.Logoff();
// Clean up.
//oRecip = null;
//oRecips = null;
oMsg = null;
oNS = null;
oApp = null;
}
// Return Error Message
catch (Exception e)
{
return e.Message;
}
// Default return value.
return "";
}

Related

How to get an ExchangeUser by email address with Outlook Object Library?

I'm currently doing a meeting finder and for that I want to read people's calendars.
I have this snippet to get the manager from the current user, however I want to get the ExchangeUser by their email adress (not the current user itself).
Outlook.ExchangeUser manager = oApp.Session.CurrentUser.AddressEntry.GetExchangeUser().GetExchangeUserManager();
How can I do that?
Edit:
This is the code that worked for me (not optimized yet):
private static Outlook.Application _oApp;
static void Main(string[] args)
{
_oApp = GetApplicationObject();
if (_oApp == null) {
Console.WriteLine("Unable to connect to a running Outlook instance or create a new one");
return;
}
Outlook.NameSpace oNamespace = _oApp.GetNamespace("MAPI");
try
{
var user1Recipient = GetUserByEmailAddress("user1#example.tld");
var user1 = user1Recipient.AddressEntry.GetExchangeUser();
Console.WriteLine($"{user1.PrimarySmtpAddress}: {user1.Name}");
try
{
Outlook.Folder folder = _oApp.Session.GetSharedDefaultFolder(user1Recipient, Outlook.OlDefaultFolders.olFolderCalendar) as Outlook.Folder;
folder.Display();
}
catch
{
Console.WriteLine($"Could not open {user1.Name}'s calendar!");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error {ex}");
}
finally
{
oNamespace.Logoff();
}
Console.ReadLine();
}
private static Outlook.Recipient GetUserByEmailAddress(string email)
{
Outlook.Recipient recipient = null;
try
{
Outlook._MailItem mailItem = _oApp.CreateItem(Outlook.OlItemType.olMailItem) as Outlook._MailItem;
recipient = mailItem.Recipients.Add(email);
recipient.Resolve();
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex);
}
return recipient;
}
private static Outlook.Application GetApplicationObject()
{
Outlook.Application oApp = null;
if (Process.GetProcessesByName("OUTLOOK").Any())
{
oApp = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
}
else
{
oApp = new Outlook.Application();
Outlook.NameSpace oNamespace = oApp.GetNamespace("MAPI");
oNamespace.Logon("", "", Missing.Value, Missing.Value);
}
return oApp;
}
Could this work for you?
In C#:
public static Outlook.Recipient GetUserByMail(string mailAddress)
{
Outlook.Recipient r = null;
try
{
// TO DO: re-use existing application, if possible
Outlook.Application OL = new Outlook.Application();
Outlook._MailItem mail =
OL.CreateItem(Outlook.OlItemType.olMailItem)
as Outlook._MailItem;
r = mail.Recipients.Add(mailAddress);
r.Resolve();
}
catch (Exception)
{
}
return r;
}
In VBA:
Function GetUserByMail(mailAddress As String) As Recipient
Dim myItem As mailItem
Dim myRecipient As Recipient
On Error GoTo ErrHandler
Set myItem = Application.CreateItem(olMailItem)
Set myRecipient = myItem.recipients.Add(mailAddress)
myItem.recipients.ResolveAll
Set GetUserByMail = myItem.recipients.item(1)
On Error GoTo 0
Exit Function
ErrHandler:
Set GetUserByMail = Nothing
Err.Clear
On Error GoTo 0
End Function
Pass the email address to oApp.Session.CreateRecipient, call Recipient.Resolve, then call Recipient.AddressEntry.GetExchangeUser(). Be prepared to handle nulls and exceptions.

Set custom message for Follow-up text on email - EWS c#

I have developed an engine to automatically process the emails sent to a particular mailbox using EWS (Exchange Web Services) Push Subscription. Everything is working fine except, I need to set the follow-up flag text with some custom message like we do in outlook (screen-shots below):
Custom text:
Sample email after setting the flag text:
I am using below code to do that, however the text is not displayed on email, only dates are reflecting with below code:
public bool MoveToFolder(EmailMessage mail, string folderName, bool MarkForFollowUp, string FollowUpText)
{
try
{
var folderView = new FolderView(100);
if (MarkForFollowUp)
{
try
{
ExtendedPropertyDefinition followUpTextFlag = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "ChangeDetails", MapiPropertyType.String);
Flag flag = new Flag();
flag.FlagStatus = ItemFlagStatus.Flagged;
flag.StartDate = DateTime.Now;
flag.DueDate = DateTime.Now.AddHours(1);
mail.Flag = flag;
workLog.WriteVerbose($"Setting flag with followup-text: {FollowUpText}", "Notify.cs > MoveToFolder()");
mail.SetExtendedProperty(followUpTextFlag, FollowUpText);
mail.Update(ConflictResolutionMode.AutoResolve);
workLog.WriteVerbose($"Message follow-up flag set successfully.", "Notify.cs > MoveToFolder()");
}
catch (Exception ex)
{
// Ignore error while settings the flag
workLog.WriteVerbose($"Error occurred while setting the follow-up flag. Reason: {ex.Message}", "Notify.cs > MoveToFolder()");
}
}
folderView.PropertySet = new PropertySet(BasePropertySet.IdOnly);
folderView.PropertySet.Add(FolderSchema.DisplayName);
folderView.Traversal = FolderTraversal.Deep;
FindFoldersResults findFolderResults = _service.FindFolders(WellKnownFolderName.Root, folderView);
if (findFolderResults == default(FindFoldersResults))
{
return false;
}
try
{
FolderId folderId = findFolderResults.Cast<Folder>().FirstOrDefault(Folder => Folder.DisplayName == folderName).Id;
mail.Move(folderId);
return true;
}
catch
{
return false;
}
}
catch (Exception)
{
return false;
}
}
You need to set the PidLidFlagRequest extended property https://learn.microsoft.com/en-us/office/client-developer/outlook/mapi/pidlidflagrequest-canonical-property with the text you want to show eg
ExtendedPropertyDefinition followUpTextFlag = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "ChangeDetails", MapiPropertyType.String);
ExtendedPropertyDefinition PidLidFlagRequest = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Common, 0x8530, MapiPropertyType.String);
ExtendedPropertyDefinition PidLidFlagString = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Common, 0x85C0, MapiPropertyType.Integer);
Flag flag = new Flag();
flag.FlagStatus = ItemFlagStatus.Flagged;
flag.StartDate = DateTime.Now;
flag.DueDate = DateTime.Now.AddHours(1);
mail.Flag = flag;
mail.SetExtendedProperty(PidLidFlagRequest, "PidFlag Blah Blah");
mail.SetExtendedProperty(PidLidFlagString, 0);
mail.SetExtendedProperty(followUpTextFlag, "Blah Balh");
mail.Update(ConflictResolutionMode.AutoResolve);

How to get sender's email when Email type is EX for Outlook?

I am trying to get sender's email address for an Outlook mailbox through C# code. I tried this link but I am getting "Object reference not set to an instance of an object" for senderEmail = objAddressentry.GetExchangeUser().PrimarySmtpAddress line. My code is as follows:
Outlook.Application oApp = new Outlook.Application();
Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
Outlook.MailItem olMail = new Outlook.MailItem();
if (olMail.SenderEmailType == "EX")
{
var objReply = olMail.Reply();
var objRecipient = objReply.Recipients[1];
var strEntryId = objRecipient.EntryID;
var objAddressentry = oNS.GetAddressEntryFromID(strEntryId);
string senderEmail = objAddressentry.GetExchangeUser().PrimarySmtpAddress;
}
I will appreciate any help.
If it is of any help, I came across this link, but my AddressEntryUserType comes as olExchangeDistributionListAddressEntry, which is why the control doesn't go inside the If branch.
As pointed earlier by, my code is correct. It throws the "Object reference not set to an instance of an object" exception for objAddressentry.GetExchangeUser(), when AddressEntryUserType for Sender is of olExchangeDistributionListAddressEntry type. Modified code is as follows:
if (olMail.SenderEmailType == "EX")
{
var objReply = olMail.Reply();
Outlook.Recipient objRecipient = objReply.Recipients[1];
string strEntryId = objRecipient.EntryID;
Outlook.AddressEntry objAddressentry = oNS.GetAddressEntryFromID(strEntryId);
if (objAddressentry != null)
{
Outlook.ExchangeUser eu = objAddressentry.GetExchangeUser();
if (eu != null)
senderEmail = eu.PrimarySmtpAddress;
}
}

C# - Connect to Outlook 2010 Mailbox to take Xls Files

I had a a c# script that connects to an OFFICE 365 mailbox and then take any emails with an xls file and puts it in a shared folder. Problem is now the OFFICE 365 mailbox has becomes an Outlook 2010 on premises mailbox, and the script has stopped working.
My questions is what Service URL and service credentials do I use, Is it the same syntax or do I need a new way of connecting in the script ?
OLD script
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Exchange.WebServices.Data;
namespace ST_0710846949654fbd84606ec3011bd081.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
/*
The execution engine calls this method when the task executes.
To access the object model, use the Dts property. Connections, variables, events,
and logging features are available as members of the Dts property as shown in the following examples.
To reference a variable, call Dts.Variables["MyCaseSensitiveVariableName"].Value;
To post a log entry, call Dts.Log("This is my log text", 999, null);
To fire an event, call Dts.Events.FireInformation(99, "test", "hit the help message", "", 0, true);
To use the connections collection use something like the following:
ConnectionManager cm = Dts.Connections.Add("OLEDB");
cm.ConnectionString = "Data Source=localhost;Initial Catalog=AdventureWorks;Provider=SQLNCLI10;Integrated Security=SSPI;Auto Translate=False;";
Before returning from this method, set the value of Dts.TaskResult to indicate success or failure.
To open Help, press F1.
*/
public void Main()
{
ExchangeService service = new ExchangeService();
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
service.Credentials = new WebCredentials("xxreturns#xxxxxxxxxxxx.co.uk", "PasswordXXXXXXXXX", "mail.xxxxxxxxxxxxxxx.co.uk");
service.Url = new Uri("https://mail.xxxxxxxxxxx.co.uk/owa");
// Variable population
string FileName1 = null;
string attSaveLocation = Dts.Variables["User::attSaveLocation"].Value.ToString();
string destfold = Dts.Variables["User::destFolder"].Value.ToString();
string emailFrom = Dts.Variables["User::emailFrom"].Value.ToString();
string filetype = Dts.Variables["User::filetype"].Value.ToString();
//find items in the email folder
FindItemsResults<Item> foundItems =
service.FindItems(WellKnownFolderName.Inbox, new ItemView(600)); //can limit how many results are pulled
foreach (Item item in foundItems)
{
string tmpitemid;
string processed = null;
tmpitemid = item.Id.ToString();
if (item is EmailMessage)
{
// Bind to an existing message item, requesting its Id property (using the tmpitemid) plus its attachments collection.
EmailMessage foundEmail = EmailMessage.Bind(service, new ItemId(tmpitemid), new PropertySet(BasePropertySet.IdOnly, ItemSchema.Attachments));
EmailMessage foundEmail2 = (EmailMessage)item;
FindFoldersResults findResults = service.FindFolders(WellKnownFolderName.Inbox, new FolderView(10));
//get the from e-mail address for exchange addresses
string fromaddress = null;
NameResolutionCollection nd = service.ResolveName(foundEmail2.From.Address);
foreach (NameResolution nm in nd)
{
if (nm.Mailbox.RoutingType == "SMTP")
{
fromaddress = nm.Mailbox.Address.ToLower();
}
else
{
fromaddress = foundEmail2.From.Address.ToString().ToLower();
}
}
//for other addresses
if (fromaddress == null)
{
fromaddress = foundEmail2.From.Address.ToString().ToLower();
}
//if the email address is like the parameter
if (fromaddress.Contains(emailFrom))
{
//process attachments
foreach (Attachment attachment in foundEmail.Attachments)
{
if (attachment is FileAttachment)
{
FileAttachment fileAttachment = attachment as FileAttachment;
FileName1 = attSaveLocation + fileAttachment.Name;
if (fileAttachment.Name.Contains(filetype))
{
fileAttachment.Load(FileName1);
processed = "Y";
}
}
}
if (processed == "Y")
{
// Get all the folders in the message's root folder.
Folder rootfolder = Folder.Bind(service, WellKnownFolderName.Inbox);
rootfolder.Load();
foreach (Folder folder in rootfolder.FindFolders(new FolderView(100)))
{
if (folder.DisplayName == destfold)
{
foundEmail2.Move(folder.Id);
}
}
}
}
}
}
Dts.TaskResult = (int)ScriptResults.Success;
}
}
}
Not sure if this works for Outlook 2010, but perhaps this link can help you:
https://msdn.microsoft.com/en-us/office/office365/api/mail-rest-operations

How to retrieve CC email address from MS outlook 2010?

I am using below code to retrieve the different mail parameter from MS outlook 2010. but I am not able to get CC email address. CC property of MailItem class is returning Name, not email address.
NameSpace _nameSpace;
ApplicationClass _app;
_app = new ApplicationClass();
_nameSpace = _app.GetNamespace("MAPI");
object o = _nameSpace.GetItemFromID(EntryIDCollection);
MailItem Item = (MailItem)o;
string HTMLbpdyTest = Item.HTMLBody;
CreationTime = Convert.ToString(Item.CreationTime);
strEmailSenderEmailIdMAPI = Convert.ToString(Item.SenderEmailAddress);
strEmailSenderName = Item.SenderName;
Subject = Item.Subject;
string CCEmailAddress = Item.CC;
Please suggest, how can I get CC email addresses?
Loop through the MailItem.Recipients collection and for each Recipient object check its Type property; olCC is what you want. You can then read the Recipient.Address property.
EDIT: Off the top of my head.
foreach (Recipient recip in Item.Recipients)
{
if (recip.Type == OlMailRecipientType.olCC)
{
if (CCEmailAddress.length > 0) CCEmailAddress += ";";
CCEmailAddress += recip.Address;
}
}
I was inspired by #Dmitry's answer and tried a few things on my own to have these lines of code fix my problems and give me an array of the cc-ed addresses that are present in a given mail item.
public string[] GetCCAddress(MailItem mailItem)
{
string email;
Outlook.ExchangeUser exUser;
List <string> ccEmailAddressList = new List<string>();
foreach (Recipient recip in mailItem.Recipients)
{
if ((OlMailRecipientType)recip.Type == OlMailRecipientType.olCC)
{
email=recip.Address;
if (!email.Contains("#"))
{
exUser = recip.AddressEntry.GetExchangeUser();
email = exUser.PrimarySmtpAddress;
}
ccEmailAddressList.Add(email);
}
}
This statement if (!email.Contains("#")) is to avoid calling exUser.PrimarySmtpAddress on an actual email address and restrict that to entries such as " /O=EXG5/OU=EXCHANGE ADMINISTRATIVE GROUP (FYDIBOHF23SPDLT)/CN=RECIPIENTS/CN=Test88067"
public static int ConnectToOutlook()
{
try
{
Outlook.Application oApp = new Outlook.Application();
Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
oNS.Logon(Missing.Value, Missing.Value, false, true);
Outlook.MAPIFolder oInbox = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox).Parent;
List<string> ccRecipient = new List<string>();
foreach (MAPIFolder folder in oInbox.Folders)
{
if (folder.FullFolderPath.Contains("Inbox"))
{
foreach (MAPIFolder subFolder in folder.Folders)
{
try
{
if (subFolder.FullFolderPath.Contains("Folder Name Inside Inbox"))
{
foreach (object folderItems in subFolder.Items)
{
if (folderItems is Outlook.MailItem)
{
Outlook.MailItem email_Msg = (Outlook.MailItem)folderItems;
Console.WriteLine("Subject=>" + email_Msg.Subject);
//Console.WriteLine("From=>" + email_Msg.SenderEmailAddress);
//Console.WriteLine("Cc=>" + email_Msg.CC);
//Console.WriteLine("Recipients=>" + email_Msg.Recipients[1].Address);
foreach (Recipient recipient in email_Msg.Recipients)
{
if ((OlMailRecipientType)recipient.Type == OlMailRecipientType.olCC)
{
Console.WriteLine("Cc=>" + recipient.AddressEntry.GetExchangeUser().PrimarySmtpAddress);
}
}
}
}
}
}
catch (System.Exception error)
{
Console.WriteLine();
Console.WriteLine(error.Message);
}
}
}
}
}
catch (System.Exception e)
{
Console.WriteLine("{0} Exception caught: ", e);
}
return 0;
}
Try
Item.CC.Address
or
((MailAddress)Item.CC).Address

Categories

Resources