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.
Related
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 "";
}
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
In here comes every folder details.Now I wanted to Restric it only list "Folders under Inbox"
Actually now i wanted to list folders under inbox.(I created folders under inbox.I don't want to show Outbox,Draft & so..on )
MyCode.
private IEnumerable<MAPIFolder> GetAllFolders(Folders folders)
{
foreach (MAPIFolder f in folders)
{
yield return f;
foreach (var subfolder in GetAllFolders(f.Folders))
{
yield return subfolder;
}
}
}
Button Click event
private void button1_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Outlook.Application oApp =
new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook._NameSpace ns =
(Microsoft.Office.Interop.Outlook._NameSpace)oApp.GetNamespace("MAPI");
// in here i get the error "userd of unassign local variable".
// without this line code works fine and return all the Folders &
// Sub folders.
Microsoft.Office.Interop.Outlook.MAPIFolder oPublicFolder =
olNS.GetDefaultFolder(
Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
foreach (var f in GetAllFolders(ns.Folders))
{
//if (f == oPublicFolder) continue;
if (f.DefaultItemType == OlItemType.olMailItem)
{
string ff = f.Name;
//Some codings here
}
}
}
This is sometimes a stupid question because sometimes it maybe a pretty simple.But here i ask you from helping hands.
// Create Application class and get namespace
Outlook.Application outlook = new Outlook.ApplicationClass();
Outlook.NameSpace ns = outlook.GetNamespace("Mapi");
object _missing = Type.Missing;
ns.Logon(_missing, _missing, false, true);
// Get Inbox information in objec of type MAPIFolder
Outlook.MAPIFolder inbox = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
// Unread emails
int unread = inbox.UnReadItemCount;
// Display the subject of emails in the Inbox folder
foreach (Outlook.MailItem mail in inbox.Items)
{
Console.WriteLine(Wmail.Subject);
}
FOR FETCHING THE SUB FOLDER NAMES WITHIN INBOX
Microsoft.Office.Interop.Outlook.Application outlook = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.NameSpace ns = outlook.GetNamespace("Mapi");
object _missing = Type.Missing;
ns.Logon(_missing, _missing, false, true);
// Get Inbox information in objec of type MAPIFolder
Microsoft.Office.Interop.Outlook.MAPIFolder inbox = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
// Unread emails
int unread = inbox.UnReadItemCount;
// Display the subject of emails in the Inbox folder
foreach (Microsoft.Office.Interop.Outlook.Folder folds in inbox.Folders)
{
Console.WriteLine(folds.Name);
}
I want to import contacts from Outllok via Mapi.
First step with standard contact is no problem:
MAPIFolder contactObjects =
outlookObj.Session.GetDefaultFolder(OlDefaultFolders.olFolderContacts);
foreach (ContactItem contactObject in contactObjects.Items) {
... import contact ...
}
In a second step I additionally want to import shared contacts. Only thing I found was using
OpenSharedItem(sharedContacts.vcf)
but I don't know the name of the file (shared item) I want to open.
Does someone know how to access shared contacts and can help me out?
Tobi
Update:
Thanks for the hint with the vcf-Files. But where do I find them?
Update2:
I played around with OutlookSpy. I got access to the folder with shared contacts, but only by knowing the id (which is of course different for other users):
var ns = outlookObj.GetNamespace("MAPI");
var flr = ns.GetFolderFromID("00000000176A90DED92CE6439C1CB89AFE3668F90100D1AD8F66B576B54FB731302D9BB9F6C40007E4BAC5020000");
foreach (var contactObject in flr.Items) {
...
}
How do I get access to the folder without knowing the id?
You will need to either explicitly parse the vCard files or you can use Redemption (I am its author) - it allows to import vCard files using RDOContactItem.Import - http://www.dimastr.com/redemption/RDOMail.htm#methods
Well the solution to the question as it is asked in the title is almost simple.
You just need to call:
Recipient recip = Application.Session.CreateRecipient("Firstname Lastname");
MAPIFolder sharedContactFolder = Application.Session.GetSharedDefaultFolder(recip, OlDefaultFolders.olFolderContacts);
Because this does not solve my problem I will ask another question!
I have done some programming to get contact from outlook.
I am giving you some example code to help you up with this ..It is not excatly want you want but i think this will help you with your problem...
using System.Collections.Generic;
// ...
private List<Outlook.ContactItem> GetListOfContacts(Outlook._Application OutlookApp)
{
List<Outlook.ContactItem> contItemLst = null;
Outlook.Items folderItems =null;
Outlook.MAPIFolder mapiFoldSuggestedConts = null;
Outlook.NameSpace nameSpc = null;
Outlook.MAPIFolder mapiFoldrConts = null;
object itemObj = null;
try
{
contItemLst = new List<Outlook.ContactItem>();
nameSpc = OutlookApp.GetNamespace("MAPI");
// getting items from the Contacts folder in Outlook
mapiFoldrConts =
nameSpc.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
folderItems = mapiFoldrConts.Items;
for (int i = 1; folderItems.Count >= i; i++)
{
itemObj = folderItems[i];
if (itemObj is Outlook.ContactItem)
contItemLst.Add(itemObj as Outlook.ContactItem);
else
Marshal.ReleaseComObject(itemObj);
}
Marshal.ReleaseComObject(folderItems);
folderItems = null;
// getting items from the Suggested Contacts folder in Outlook
mapiFoldSuggestedConts = nameSpc.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderSuggestedContacts);
folderItems = mapiFoldSuggestedConts.Items;
for (int i = 1; folderItems.Count >= i; i++)
{
itemObj = folderItems[i];
if (itemObj is Outlook.ContactItem)
contItemLst.Add(itemObj as Outlook.ContactItem);
else
Marshal.ReleaseComObject(itemObj);
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
finally
{
if (folderItems != null)
Marshal.ReleaseComObject(folderItems);
if (mapiFoldrConts != null)
Marshal.ReleaseComObject(mapiFoldrConts);
if (mapiFoldSuggestedConts != null)
Marshal.ReleaseComObject(mapiFoldSuggestedConts);
if (nameSpc != null) Marshal.ReleaseComObject(nameSpc);
}
return contItemLst;
}
var outlook = new Microsoft.Office.Interop.Outlook.Application();
NameSpace mapiNamespace = outlook.Application.GetNamespace("MAPI");
foreach (Store store in mapiNamespace.Stores)
{
try
{
var folder = store.GetRootFolder();
foreach(MAPIFolder subfolder in folder.Folders)
{
if ( subfolder.Name == "Inbox")
{
foreach(dynamic message in subfolder.Items.Restrict("[MessageClass]='IPM.Sharing'"))
{
if (message.Class == 104)//SharingItem
{
Folder sharedFolder = message.OpenSharedFolder();
if (sharedFolder.DefaultMessageClass == "IPM.Contact")
{
//this is your folder
}
}
}
}
}
}
catch (System.Exception ex)
{
continue;
}
}
I have the following code to enumerate all the email address of my contacts but I am not able to do so with the exception point at this line
Outlook.ContactItem oAppt = (Outlook.ContactItem)oItems;
Could someone help me out so that I can enumerate all the email address of my contacts in Microsoft outlook ?
namespace RetrieveContacts
{
public class Class1
{
public static int Main(string[] args)
{
try
{
Outlook.Application oApp = new Outlook.Application();
Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
Outlook.MAPIFolder oContacts = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
Outlook.Items oItems = oContacts.Items;
Outlook.ContactItem oAppt = (Outlook.ContactItem)oItems;
for (int i = 0; i <= oItems.Count; i++)
{
System.IO.StreamWriter file = new System.IO.StreamWriter("C:\\EmailAddress.txt");
file.WriteLine(oAppt.Email1Address);
file.Close();
}
oNS.Logoff();
oAppt = null;
oItems = null;
oContacts = null;
oNS = null;
oApp = null;
}
catch (Exception e)
{
System.IO.StreamWriter file = new System.IO.StreamWriter("C:\\Exception.txt");
file.WriteLine(e);
file.Close();
}
return 0;
}
}
}
Without knowing Outlook's object model by heart I'd guess that Outlook.Items is a collection of ContactItems and thus cannot directly be cast to a single ContactItem. Other concerns:
You're creating and writing to your file within the loop, so it would get overwritten each time
You need to validate that the item is a ContactItem or your cast will throw an error.
the file access should be in a using block so it gets closed automatically if an Exception is thrown
Your for loop is going from 0 to Count when it should be going from 0 to Count-1 if the collection is 0-based
Try changing your loop to something like this:
Outlook.Items oItems = oContacts.Items;
using(System.IO.StreamWriter file = new System.IO.StreamWriter("C:\\EmailAddress.txt"))
{
for (int i = 0; i < oItems.Count; i++) // Note < instead of <=
{
// Will be null if oItems[i] is not a ContactItem
Outlook.ContactItem oAppt = oItems[i] as Outlook.ContactItem;
if(oAppt != null)
file.WriteLine(oAppt.Email1Address);
}
}
file.Close();
oNS.Logoff();