C# Winforms: Accessing Outlook with Multiple Mailboxes - c#

I'm trying to access an Outlook Mailbox from C# / Winforms. I have two separate mailboxes that my user profile can access. How can i code it so that it only pulls from a certain mailbox?
Here's what I have currently, but it only pulls the info from my default account mailbox.
try
{
OutLook.Application oApp = new OutLook.Application();
OutLook.NameSpace oNS = (OutLook.NameSpace)oApp.GetNamespace("MAPI");
oNS.Logon(Missing.Value, Missing.Value, false, true);
OutLook.MAPIFolder theInbox = oNS.GetDefaultFolder(OutLook.OlDefaultFolders.olFolderInbox);
int count = theInbox.UnReadItemCount;
inboxLabel.Text = inboxLabel.Text + " " + count.ToString();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
I also need to tell it certain folders along with the inbox (like above).
Thanks for the assistance in advance.

I finally figured out how to designate which mailbox I wanted to open. I'll post it here for others to use in the future.
try
{
Outlook.Application oApp = new Outlook.Application();
Outlook.NameSpace oNS = (Outlook.NameSpace)oApp.GetNamespace("MAPI");
oNS.Logon(Missing.Value, Missing.Value, false, true);
Outlook.MAPIFolder theInbox = oNS.Folders["Mailbox - Name Here"].Folders["Inbox"];
....Do you want with that Folder here....
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
Hope this helps anyone else :D

Related

Get Outlook AppointmentItem using GlobalAppointmentID

I am developing a calendar for my firm that synchronizes with Outlook Calendar.
Atm I can:
import appointments from Outlook and show them in my calendar
update my appointments when Outlook appointments get updated
create Outlook appointments when appointments get created in my calendar
The only issue I have is updating/deleting Outlook appointments when my appointments update/delete.
I have the GlobalAppointmentID of the corresponding appointments but I can't seem to search on that ID.
I tried:
using Microsoft.Office.Interop;
private void GetAppointment(string myGlobalAppointmentID)
{
Outlook.Application oApp = new Outlook.Application();
Outlook.NameSpace mapiNamespace = oApp.GetNamespace("MAPI");
Outlook.MAPIFolder calendarFolder = mapiNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
Outlook.Items outlookCalendarItems = calendarFolder.Items;
Outlook.AppointmentItem appointmentItem = (Outlook.AppointmentItem)outlookCalendarItems.Find("[GlobalAppointmentID] = '{0}'", myGlobalAppointmentID));
//update or delete appointmentItem here (which I know how to do)
}
I keep getting 'Condition is not valid' Exception.
Apparently Outlook does not allow to search on binary properties (such as GlobalAppointmentID).
I use the same outlookCalendarItems.Find() and calendarFolder.Items.Restrict() without problems in other instances.
I tried using Redemption but I couldn't get it to work either.
Does anybody have experience or a suggestion?
Yes, OOM won't let you search on binary properties (as well as recipients or attachments), but Redemption (I am its author) should work. The following script (VBA) worked just fine for me:
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Folder = Session.GetDefaultFolder(olFolderCalendar)
set appt = Folder.Items.Find("GlobalAppointmentID = '040000008200E00074C5B7101A82E00800000000D0FECEE58FEAD70100000000000000001000000041C887A3FA12694F8A0402FEFFAD0BBB'")
MsgBox appt.Subject
The Outlook object model doesn't support searching for binary properties such as GlobalAppointmentId (any other PT_BINARY property) with Items.Find/Items.FindNext/Items.Restrict.
The only workaround is to loop through all item in the Calendar folder (which is inefficient) or search using Extended MAPI (or using third-party wrappers such as Redemption.
What I ended up doing after looking further:
I added a text UserProperty where I put the GlobalAppointmentID("GAID") in.
You can Filter on those.
And it seems to do the trick.
private void AddGAIDIfNeeded(Outlook.AppointmentItem app)
{
bool GAIDexists = false;
if (app.UserProperties.Count != 0)
{
foreach (UserProperty item in app.UserProperties)
{
if (item.Name == "GAID")
{
GAIDexists = true;
break;
}
}
}
if (GAIDexists == false)
{
app.UserProperties.Add("GAID", Outlook.OlUserPropertyType.olText);
app.UserProperties["GAID"].Value = app.GlobalAppointmentID;
app.Save();
}
}
And to find a specific AppointmentItem:
private void DeleteOutlookAppointmentByGAID(string globalAppointmentID)
{
Outlook.Application oApp = new Outlook.Application();
Outlook.NameSpace mapiNamespace = oApp.GetNamespace("MAPI");
Outlook.MAPIFolder calendarFolder = mapiNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
Outlook.Items outlookCalendarItems = calendarFolder.Items;
try
{
Outlook.AppointmentItem appointmentItem = null;
appointmentItem = outlookCalendarItems.Find(String.Format("[GAID] = '{0}'", globalAppointmentID));
if (appointmentItem != null)
{
appointmentItem.Delete();
}
}
catch (Exception ex)
{
classExecptionLogging.LogErrorToFolder(ex);
}
}

Interop Outlook - Sending Appointment from another mailbox

I have two mailboxes setup in Outlook.
I'll refer to them as "email1#mail.com" and "email2#mail.com".
I would like to use Interop to create and send an appointment to a specific email address calender, not just to the default outlook account.
using System;
using System.Diagnostics;
using System.Reflection;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace Program
{
class Program
{
public static void Main(string[] args)
{
// Create the Outlook application.
Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
Outlook.Account account = oApp.Session.Accounts["email2#mail.com"];
// 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 = "test";
// Set HTMLBody.
oMsg.HTMLBody = "test";
oMsg.To = "test#gmail.com";
//oMsg.CC = _cc;
//oMsg.BCC = _bcc;
oMsg.Save();
oMsg.SendUsingAccount = account;
// Add a recipient.
//Microsoft.Office.Interop.Outlook.Recipients oRecips = (Microsoft.Office.Interop.Outlook.Recipients)oMsg.Recipients;
// TODO: Change the recipient in the next line if necessary.
//Microsoft.Office.Interop.Outlook.Recipient oRecip = (Microsoft.Office.Interop.Outlook.Recipient)oRecips.Add(_recipient);
//oRecip.Resolve();
// 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;
}
}
}
This code works flawlessly in sending an email automatically to "test#gmail.com" from my email "email2#mail.com".
However, I would like to automatically create an appointment/meeting for a specific email address.
This is my current attempt:
using System;
using System.Diagnostics;
using System.Reflection;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace SendEventToOutlook
{
class Program
{
public static void Main(string[] args)
{
try
{
// Create the Outlook application.
Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
Outlook.Account account = oApp.Session.Accounts["email2#mail.com"];
// 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 Appointment item.
Microsoft.Office.Interop.Outlook.AppointmentItem appt =
(Microsoft.Office.Interop.Outlook.AppointmentItem)
oApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olAppointmentItem);
appt.Start = DateTime.Now;
appt.End = DateTime.Now.AddDays(7);
appt.Location = "Test";
appt.Body = "Test";
appt.AllDayEvent = false;
appt.Subject = "Test";
appt.Save();
appt.SendUsingAccount = account;
// Log off.
oNS.Logoff();
appt = null;
oNS = null;
oApp = null;
}
catch (Exception ex)
{
Debug.WriteLine("The following error occurred: " + ex.Message);
}
}
}
}
This code does create an appointment successfully, but it keeps creating an appointment for "email1#mail.com" instead of "email2#mail.com", which shouldn't happen as I've specified the sending account to be "email2#mail.com" from the lines:
Outlook.Account account = oApp.Session.Accounts["email2#mail.com"];
and then
appt.SendUsingAccount = account;
This is how my two email addresses are set up in Outlook: http://i.imgur.com/0eopV8A.png
Both the email addresses have different user names and are from different domains/mail servers, as shown in that screenshot.
Would anyone be able to see the problem I'm making or if there's a different solution?
Thank you.
It is not clear whether you have got two accounts set up in the single Mail profile or separate profiles.
The SendUsingAccount property of the AppointmentItem class allows to set an Account object that represents the account under which the AppointmentItem is to be sent. So, The SendUsingAccount property can be used to specify the account that should be used to send the AppointmentItem when the Send method is called. It is not what you are looking for I suppose.
Anyway, you can use the GetDefaultFolder method of the Store class which returns a Folder object that represents the default folder in the store and that is of the type specified by the FolderType argument. This method is similar to the GetDefaultFolder method of the NameSpace object. The difference is that this method gets the default folder on the delivery store that is associated with the account, whereas NameSpace.GetDefaultFolder returns the default folder on the default store for the current profile.
Thus, you can get the Calendar folder for the required account and add a new appointment there.
You may find the following articles in MSDN helpful:
How to: Create a Sendable Item for a Specific Account Based on the Current Folder (Outlook)
Using Multiple Accounts for the Same Profile on Outlook

Empty out file on different PCs C#.NET Add-in Outlook

I have the next problem. I've written the solution for MS Outlook 2010 that creates email summary and write it down to an Excel file(.xls) The problem is that on my PC and several others it works correctly but when I sent it to customers, they said that it creates summary only for inbox folder on some PCs and on others it doesn't work at all.
I've also created the possibility to choose the folder to get the emails but the problem left. I'll provide a code snippet of the function choosing folder and getting the list of emails. I save emails in List in private field of my class.
Take a look on this func and please help to get out what is wrong. Thanks.
public void GetTheArrayOfEmails(DateTime startDate, DateTime finishDate)
{
try
{
Outlook.Application oApp = new Outlook.Application();
Outlook.NameSpace oNs = oApp.GetNamespace("mapi");
oNs.Logon(Missing.Value, Missing.Value, false, false);
//Outlook.MAPIFolder folder = oApp.Session.PickFolder();
foreach (Outlook.MailItem oMsg in oApp.Session.PickFolder().Items)
{
if (oMsg.ReceivedTime.ToUniversalTime() > startDate.ToUniversalTime() &&
oMsg.ReceivedTime.ToUniversalTime() < finishDate.ToUniversalTime())
{
MailList.Add(oMsg);
}
}
oNs.Logoff();
releaseObject(oNs);
releaseObject(oApp);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
UPD: Fixed the problem. I missed cast. And tried to cast items which are not of MailItem interface.

Outlook logon error in csharp

I use this code to check if the Outlook application is open and if not create a new process and logon.
try
{
Outlook.Application oApp = null;
if (System.Diagnostics.Process.GetProcessesByName("OUTLOOK").Count() > 0)
{
oApp = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
}
else oApp = new Outlook.Application();
Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
oNS.Logon(Type.Missing, Type.Missing, false, true);
return oNS.CurrentUser.Name;
}
catch (Exception exp)
{
Logger.AddMessage(exp.ToString());
}
If the program is open I have no issues but when try to start it in csharp I get this logon error:
"The server is not available. Contact your administrator if this condition persists."
Something missed or what is wrong here?
First set the third parameter to true to see the available profiles to select, then set the default profile name!
void Logon(
Object Profile,
Object Password,
Object ShowDialog,
Object NewSession
)
In my case:
oNS.Logon("Default Outlook Profile", "", false, true);

How to get unread mail from the specific folder

I am using below code to check unread mail from the outlook
and everything is working fine for the default inbox folder
Microsoft.Office.Interop.Outlook.Application oApp;
Microsoft.Office.Interop.Outlook._NameSpace oNS;
Microsoft.Office.Interop.Outlook.MAPIFolder oFolder;
Microsoft.Office.Interop.Outlook._Explorer oExp;
oApp = new Microsoft.Office.Interop.Outlook.Application();
oNS = (Microsoft.Office.Interop.Outlook._NameSpace)oApp.GetNamespace("MAPI");
oFolder = oNS.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
oExp = oFolder.GetExplorer(false);
oNS.Logon(Missing.Value, Missing.Value, false, true);
Microsoft.Office.Interop.Outlook.Items items = oFolder.Items;
foreach (Object mail in items)
{
if ((mail as Microsoft.Office.Interop.Outlook.MailItem) != null && (mail as Microsoft.Office.Interop.Outlook.MailItem).UnRead == true)
{
string sasd= (mail as OutLook.MailItem).Subject.ToString();
}
}
But I want to check another folder [which I have created [Name = "Inbox_Personal"]]. How can I do that?
Edit 1
Any suggestion or reference to the tutorial will be appreciated.
I use something similar to the following to access different accounts in Outlook (2007 and greater; before 2007 stores do not exist and you simply need to look at the folders)
Microsoft.Office.Interop.Outlook.Application oApp;
Microsoft.Office.Interop.Outlook.NameSapce oNS = oApp.GetNameSpace(“Mapi”);
foreach(Microsoft.Office.Interop.Outlook.Store oAccounts in oNS.Stores)
{
// get the right account:
Microsoft.Office.Interop.Outlook.Store oDesiredAccount;
foreach(Microsoft.Office.Interop.Outlook.Store oAccount in oAccounts)
{
if(oAccount.DisplayName.ToLower.Equals(“<<Name of Account>>”)
{
oDesiredAccount = oAccount;
}
}
// do stuff with the account
Microsoft.Office.Interop.Outlook.MAPIFolder root = oAccount.GetRootFolder();
// ....
}
var fld = (Outlook.Folder)app.Session.GetFolderFromID("Inbox_Personal", storeID);
I can't remember where to get the store ID from, but should be stored in your session object oder default folder object.
EDIT
I've looked up in a project now: StoreID in GetFolderFromID is optional (Type.Missing).
Default Store ID can be found here:
app.Session.DefaultStore.StoreID
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook._namespace.defaultstore(v=office.12).aspx

Categories

Resources