Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / productivity / Office

AddOn Programming and an Outlook AddIn2

3.00/5 (1 vote)
9 Feb 2011CPOL4 min read 30.9K  
AddIn - AddOn programming and An Example for Outlook AddIn Regions, Views, Rules and Reports

Introduction

I have recognized that there is not enough information about OutlookAddIn programming on the internet, therefore I decided to write this article. I have searched many websites and I have read some interesting books about AddIn Programming. After some of my professional works, I have found out some critical solutions for new AddIn Programmers and I am here.

This article identifies some critical details that are interesting.

Contents

  • Regions
  • EventHandlers
  • Reports
  • Task, Mail and Appointment Management
  • Operational System and Version Detection
  • Views
  • Rules

Start Up

C#
#region Definitions 

public static Outlook.Inspectors inspectors; 
public static string _targetPath = "C:\\Users\\" + "testing\\"; 
public static string _liveMeeting = "C:\\ Logs\\LiveMeetings.txt"; 
public static bool _regionSender = false; 
private static string _operationSystemVersion = string.Empty; 
private static Timer _tm = new Timer(); 
private static bool _timerSwitch = false; 
private static ThisAddIn _instance = null; 
private static bool _manuelCancel = false; 
private static Outlook.AppointmentItem _aitm = null; 
private static bool _isLiiveMessageShowing = true; 
private static string _targetPathWin7 = "C:\\Users\\" + Environment.UserName + 
    "\\AppData\\Roaming\\Comp\\MeetingTools\\"; 
private static string _targetPathXp = "C:\\Documents and Settings\\" + 
    Environment.UserName + "\\Application Data\\Comp\\MeetingTools\\"; 
private int _meetingCount = 0; 
private int _meetingCountOwner = 0; 
private int _livmeetingCount = 0; 
private double _weeklyWorkingHours = 45; 
private double _dailyWorkingPercentace = 0; 
private TimeSpan _totalMeetingTime = new TimeSpan(); 
private string _logRoute = "C:\\Logs"; 
private string _logLocation = "C:\\Logs\\Reports.txt"; 
int counter = 0; 
bool _senderTriggered = false; 
private static DataSet _ds = new DataSet(); 
private static DataSet _dSet = new DataSet(); 
AppointmentItem ai; 
static bool _deleteTrigered = false; 
static string _domainName = "comuty"; 
bool _isOkeMailSettings = true; 
#endregion

An AddIn starts with some event handler because if the programmer wants to do some things according to some conditions in an office program, it gives up an event to the programmer and he can handle this event and he can use it according to his aims. An event handler begins like below at the startup.

C#
private void InternalStartup() 
{ 
    //CreateActionRule(); 

    this.Startup += new System.EventHandler(ThisAddIn_Startup); 
    this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown); 
}

After this progress, the programmer may use the next steps.

C#
private void ThisAddIn_Startup(object sender, System.EventArgs e) 
{ 
    if (_operationSystemVersion.Equals(string.Empty)) 
        _operationSystemVersion = FindVersion(); 
    if (_operationSystemVersion.Equals("XP")) 
        _targetPath = _targetPathXp; 
    else if (_operationSystemVersion.Equals("Win7")) 
        _targetPath = _targetPathWin7; 

    //CreateCustomAksiyonViewIfNotExist(); 
    inspectors = this.Application.Inspectors; 
    inspectors.NewInspector += 
        new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(
        inspectors_NewInspector); 
    _instance = this; 
}

Business Logic

Inserting a Button to the Tool Bar or Context Menu, catching some screens for changing their algorithms according to the necessities and releasing full requirements are the main factors in an AddIn program. So, we can write all these phases starting from the inspector which we have handled in the Start Up event before. Current Item gives us the substantial element when the event fired. I have handled Appointment Item in this case like below. I will use timer object to draw a graphic to the current window that user has entered. After this operation, I am calling the ReportInspector function for an inspection if any report exists than I send this report to the current user as a mail.

C#
void inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector) 
{ 
    _deleteTrigered = false; 
    _manuelCancel = false; 
    _senderTriggered = false; 
    if (_isOkeMailSettings) 
    { 
        SetDataSet(); 
        _isLiiveMessageShowing = IsLiveMeetingShowing(DateTime.Now, Inspector); 
        ReportInspector(DateTime.Now, Inspector); 
    } 

    Object anitem = (Outlook.AppointmentItem)Inspector.CurrentItem; 
    ai = (Outlook.AppointmentItem)Inspector.CurrentItem; 
    if (anitem != null) 
    { 
        _aitm = (Outlook.AppointmentItem)anitem; 
        if (_aitm.Body == null) 
        { 
            _tm.Interval = 10; 
            _tm.Tick += new EventHandler(tm_Tick); 
            _timerSwitch = true; 
            _tm.Start(); 
        } 
    } 
}

When we have handled the new appointment window, than we can capture its content over to make a new special design by using some tables and graphical COM Objects. The content is a Document Class in here.

C#
void tm_Tick(object sender, EventArgs e) 
{ 
    if (_timerSwitch) 
    { 
        _timerSwitch = false; 
        _tm.Stop(); 
        object ranger = (
	Application.ActiveInspector().WordEditor as 
	Microsoft.Office.Interop.Word.DocumentClass).Application.Selection.Range; 
        object linToFile = true; 
        object saveWithDocument = true; 

        string path = System.AppDomain.CurrentDomain.BaseDirectory.ToString(); 
        ((Application.ActiveInspector().WordEditor as 
	Microsoft.Office.Interop.Word.DocumentClass)).InlineShapes. 
            AddPicture(path + "\\Resources\\comunuty.jpg", 
        ref linToFile, ref saveWithDocument, ref ranger); 
        Microsoft.Office.Interop.Word.Range range1 = (
	Application.ActiveInspector().WordEditor as 
	Microsoft.Office.Interop.Word.DocumentClass).Application.Selection.Range; 
        range1.Start = 0; 
        range1.Font.Size = 12; 
        range1.Font.Name = "Calibri"; 
        range1.Orientation = Microsoft.Office.Interop.Word.
			WdTextOrientation.wdTextOrientationHorizontal; 
        range1.Text = "\r\v\v\v\v\v\v\v\v\v\r"; 
        range1.Font.Color = Microsoft.Office.Interop.Word.WdColor.wdColorBlack; 
        range1.End = 1; 

        Microsoft.Office.Interop.Word.Range range = (
	Application.ActiveInspector().WordEditor as 
	Microsoft.Office.Interop.Word.DocumentClass).Application.Selection.Range; 
        range.Start = 1; 
        range.Font.Size = 12; 
                range.Font.Name = "Calibri"; 
        range.Orientation = Microsoft.Office.Interop.
		Word.WdTextOrientation.wdTextOrientationHorizontal; 
        range.Text = "   Header"; 
        range.Font.Bold = 1; 
        range.Font.Italic = 1; 
        range.End = 2; 

        ((Outlook.ItemEvents_10_Event)Application.ActiveInspector().
		CurrentItem).BeforeDelete += 
            new ItemEvents_10_BeforeDeleteEventHandler(ThisAddIn_BeforeDelete); 
        this.Application.ItemSend += new ApplicationEvents_11_ItemSendEventHandler
				(Application_ItemSend); 
        ((Outlook.ItemEvents_10_Event)Application.
		ActiveInspector().CurrentItem).Close += 
            new ItemEvents_10_CloseEventHandler(ThisAddIn_Close); 
    } 
}

Close and Send Event handlers are providing some kind of special behaviors when this item has been sent or closed by the user interaction. I have used many control codes when this item has been closed and sending. I have recognized which button user has entered from the algorithms in the Close event because Close event is working in every scenario which user has altered in the user interface.

C#
void Application_ItemSend(object Item, ref bool Cancel)
{
try
{
         this.Application.ItemSend -= new ApplicationEvents_11_ItemSendEventHandler(
             Application_ItemSend);

   bool _mayReturn = false;

   if (!_domainName.Equals("comunuty") ||
       (Application.ActiveInspector().CurrentItem as AppointmentItem) == null)
      return;

   _senderTriggered = true;

   if (_regionSender)
   {
      _regionSender = false;
      Cancel = false;
      return;
   }

   if ((
   Application.ActiveInspector().CurrentItem as AppointmentItem).
   MeetingStatus.ToString().Equals("olMeetingCanceled"))
      return;

   ((Application.ActiveInspector().WordEditor as
   Microsoft.Office.Interop.Word.DocumentClass)).WebOptions.AllowPNG = true;

   string attendees = GetCurrentUserAddress() + ";" +
       GetRecipients(Application.ActiveInspector().
       CurrentItem as Outlook.AppointmentItem);

   //MessageBox.Show("req:" + attendees);
   if (attendees.Contains("@"))
   {
      foreach (DataRow dr in _dSet.Tables[0].Rows)
      {
         if (dr.ItemArray[0].ToString().TrimStart().TrimEnd().Equals(attendees))
         {
            attendees = dr.ItemArray[0].ToString();
            string worker = dr.ItemArray[0].ToString();
            break;
         }
      }
   }

   if (!Cancel && IsLiveMeeting(attendees,
       (Application.ActiveInspector().CurrentItem as Outlook.AppointmentItem).Location))
   {
      WarningLiveMeeting wlm = new WarningLiveMeeting();
      wlm.StartPosition = FormStartPosition.CenterScreen;
      if (wlm.ShowDialog() == DialogResult.OK)
      {
         if (wlm._sellection)
         {
            Cancel = true;
            return;
         }
         _mayReturn = true;
      }
   }

if (!_manuelCancel)
{
   int sameAppointment = 0;
   WarningWindow1 ww1 = null;
   List<AppointmentItem> items = GetAppointments((
       Application.ActiveInspector().CurrentItem as AppointmentItem).Start,
      (Application.ActiveInspector().CurrentItem as AppointmentItem).End);
   (Application.ActiveInspector().CurrentItem as AppointmentItem).Save();
   string uniqId1 = (
       Application.ActiveInspector().CurrentItem as AppointmentItem).EntryID;
   AppointmentItem eklenecekEleman = (
       Application.ActiveInspector().CurrentItem as AppointmentItem);
   bool switchReturn = false;
   bool equalityControlSwitch = false;
   bool isCase1 = false;

   try
   {
      foreach (AppointmentItem second in items)
      {
         TimeSpan scale1 = new TimeSpan(0, 0, 0);
         TimeSpan scale2 = new TimeSpan(0, 10, 0);
         TimeSpan storage = new TimeSpan(0, 0, 0);
         TimeSpan oneHour = new TimeSpan(1, 0, 0);
         string uniqId2 = second.EntryID;
         if (!uniqId1.Equals(uniqId2))
         {
            if (!equalityControlSwitch)
            {
               equalityControlSwitch = true;
               int ind = 0;
               foreach (AppointmentItem guncelEleman in items)
            {
                  bool yenininSonuBasiIleEskininSonuBasininCakismasi = false;

                  if (ind + 1 <= items.Count)
                  {
                  int difference = 99999999;
                     AppointmentItem biSonrakiEleman = null;
                     foreach (AppointmentItem sonraki in items)
                     {
                     int guncelElemanDateValue = (eklenecekEleman.Start.Year * 8760) +
                        (eklenecekEleman.Start.Month * 720) +
                        (eklenecekEleman.Start.Day * 24) + eklenecekEleman.Start.Hour;
                        int sonrakiElemanDateValue = (sonraki.Start.Year * 8760) +
                        (sonraki.Start.Month * 720) + (sonraki.Start.Day * 24) +
                         sonraki.Start.Hour;

                        if (guncelElemanDateValue < sonrakiElemanDateValue)
                     {
                           if (difference > sonrakiElemanDateValue -
                   guncelElemanDateValue)
                           {
                              difference = sonrakiElemanDateValue -
                   guncelElemanDateValue;
                              biSonrakiEleman = sonraki;
                           }
                        }
                     }


                     if (biSonrakiEleman == null)
                        continue;

                     if (eklenecekEleman.Start == guncelEleman.End &&
               eklenecekEleman.End == biSonrakiEleman.Start)
                        yenininSonuBasiIleEskininSonuBasininCakismasi = true;
                  }
                  // CASE1
                  if (yenininSonuBasiIleEskininSonuBasininCakismasi)
                     ;
                  // CASE1
                  if (yenininSonuBasiIleEskininSonuBasininCakismasi &&
               (eklenecekEleman.End.Ticks - eklenecekEleman.Start.Ticks) >
                           oneHour.Ticks &&
                  !guncelEleman.EntryID.Equals(eklenecekEleman.EntryID)
                  )
                  {
                           ww1 = new WarningWindow1();
                     ww1.StartPosition = FormStartPosition.CenterScreen;
                     if (ww1.ShowDialog() == DialogResult.OK)
                  {
                        isCase1 = true;
                        switchReturn = true;
                        if (ww1._button == "2")
                        {
                           storage = eklenecekEleman.End - eklenecekEleman.Start;
                           eklenecekEleman.Start = eklenecekEleman.Start + scale2;
                        eklenecekEleman.End = eklenecekEleman.End - (scale2 + scale2);
                           if (eklenecekEleman.RequiredAttendees == null ||
                              eklenecekEleman.RequiredAttendees.Equals(string.Empty))
                              eklenecekEleman.Save();
                           //else eklenecekEleman.Send();
                           return;
                        }
                        else if (ww1._button == "3")
                        {
                           Cancel = true;
                           return;
                        }
                        else if (ww1._button == "1")
                        {
                           return;
                        }
                     }
                  }
                  else if (yenininSonuBasiIleEskininSonuBasininCakismasi &&
                  (eklenecekEleman.End.Ticks - eklenecekEleman.Start.Ticks)
                       <= oneHour.Ticks &&
                  !guncelEleman.EntryID.Equals(eklenecekEleman.EntryID)
                  )
                  {
                     return;
                  }
                  ind++;
               }
               if (switchReturn)
                  break;
            }
         }
         else
         {
            // if comparsion is happening for the same appointment
            if (sameAppointment > 1)
            {
               ww1 = new WarningWindow1();
               if (ww1.ShowDialog() == DialogResult.OK)
               {
                  if (ww1._sellection)
                  {
                     _manuelCancel = true;
                     Cancel = true;
                  }
               }
               break;
         }
            sameAppointment++;
         }
      }
   }
   catch (System.Exception ex)
   {
      string mes = ex.Message;
   }

         // Case2 and Case3

   if (!isCase1)
   {
      bool equalityControlSwitch2 = false;
      string uniqId11 = (Application.ActiveInspector().
       CurrentItem as AppointmentItem).EntryID;
      foreach (AppointmentItem second in items)
      {
         TimeSpan scale1 = new TimeSpan(0, 0, 0);
         TimeSpan scale2 = new TimeSpan(0, 10, 0);
         TimeSpan storage = new TimeSpan(0, 0, 0);
         TimeSpan oneHour = new TimeSpan(1, 0, 0);
         string uniqId2 = second.EntryID;
         if (!uniqId11.Equals(uniqId2))
         {
         if (!equalityControlSwitch2)
            {
               equalityControlSwitch2 = true;
               int ind = 0;
               foreach (AppointmentItem guncelEleman in items)
               {
                  //******************
                  bool yenininBasiIleEskininSonuCakismasi = false;
                  bool yenininSonuIleEskininBasininCakismasi = false;


                  //CASE2
                  if (eklenecekEleman.Start == guncelEleman.End)
                     yenininBasiIleEskininSonuCakismasi = true;
                  //CASE3
                  else if (eklenecekEleman.End == guncelEleman.Start)
                     yenininSonuIleEskininBasininCakismasi = true;

                  //CASE2
                  if (yenininBasiIleEskininSonuCakismasi &&
                     !guncelEleman.EntryID.Equals(eklenecekEleman.EntryID)
                     )
                  {
                           ww1 = new WarningWindow1();
                     ww1.StartPosition = FormStartPosition.CenterScreen;
                     if (ww1.ShowDialog() == DialogResult.OK)
                  {
                        switchReturn = true;
                        if (ww1._button == "2")
                        {
                           DateTime endd = eklenecekEleman.End;
                           eklenecekEleman.Start = eklenecekEleman.Start + scale2;
                           eklenecekEleman.End = endd;
                        if (eklenecekEleman.RequiredAttendees == null ||
                              eklenecekEleman.RequiredAttendees.Equals(string.Empty))
                              eklenecekEleman.Save();
                           //else eklenecekEleman.Send();
                           return;
                        }
                        else if (ww1._button == "3")
                        {
                           Cancel = true;
                           return;
                        }
                        else if (ww1._button == "1")
                        {
                           return;
                        }
                     }
                  }

               // CASE3
                  if (yenininSonuIleEskininBasininCakismasi &&
                  !guncelEleman.EntryID.Equals(eklenecekEleman.EntryID)
                  )
               {
                     ww1 = new WarningWindow1();
                     ww1.StartPosition = FormStartPosition.CenterScreen;
                     if (ww1.ShowDialog() == DialogResult.OK)
                           {
                        switchReturn = true;
                        if (ww1._button == "2")
                        {
                        DateTime startt = eklenecekEleman.Start;
                           eklenecekEleman.End = eklenecekEleman.End - scale2;
                           eklenecekEleman.Start = startt;
                           if (eklenecekEleman.RequiredAttendees == null ||
                              eklenecekEleman.RequiredAttendees.Equals(string.Empty))
                              eklenecekEleman.Save();
                           //else eklenecekEleman.Send();
                           return;
                        }
                        else if (ww1._button == "3")
                        {
                           Cancel = true;
                           return;
                        }
                        else if (ww1._button == "1")
                        {
                           return;
                        }
                     }
                  }
                  //****************
                  ind++;
               }
               if (switchReturn)
                  break;
            }
         }
               else
         {
            // if comparsion is happening for the same appointment
            if (sameAppointment > 1)
            {
               ww1 = new WarningWindow1();
               if (ww1.ShowDialog() == DialogResult.OK)
               {
                  if (ww1._sellection)
                  {
                     _manuelCancel = true;
                     Cancel = true;
                  }
               }
               break;
            }
            sameAppointment++;
         }
      }
   }
}

   if (AppointmentRegion._inProgress)
      AppointmentRegion._inProgress = false;

   //(((Application.ActiveInspector().WordEditor as
   //    Microsoft.Office.Interop.Word.DocumentClass)).Content as
   //    Outlook.MailItem).BodyFormat = OlBodyFormat.olFormatUnspecified;

   if (_mayReturn)
      return;
}
      catch (System.Exception ex)
{
   MessageBox.Show(ex.ToString());
}

Reports

We can get periodical statistics as a report in some way. Also, we can take some reports from Exchange Server. I will show you some personal reports taken by this scenario.

GetMonthlyReport function gets the default MAPI folder to identifying how many meetings user has released and how much time he spent in the last month.

C#
 public List<Outlook.AppointmentItem> GetMonthlyReport()
 {
 counter = 0;

 Outlook.MAPIFolder mpiFolder = 
   Application.GetNamespace("MAPI").GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
 var appItems = new List<Outlook.AppointmentItem>();
 _meetingCountOwner = 0;
 _meetingCount = 0;
 _totalMeetingTime = new TimeSpan(0, 0, 0);
 _livmeetingCount = 0;

 DateTime startdate = new DateTime
	(DateTime.Now.Date.Year, DateTime.Now.Date.Date.Month - 1, 1, 0, 0, 0);
 DateTime ddd = new DateTime(DateTime.Now.Date.Year, DateTime.Now.Date.Month, 1, 0, 0, 0);
 DateTime enddate = ddd.AddDays(-1);

 mpiFolder.Items.Sort("[Start]", false);
 mpiFolder.Items.IncludeRecurrences = true;
 String sCriteria;

 string sDate = startdate.Day.ToString() + "." + 
	startdate.Month.ToString() + "." + startdate.Year.ToString() + " 00:00";
 string eDate = enddate.Day.ToString() + "." + 
	enddate.Month.ToString() + "." + enddate.Year.ToString() + " 23:59";

 sCriteria = "[Start] < '" + eDate + "' and [End] > '" + sDate + "'";

 Outlook.Items oRestrictedItems = mpiFolder.Items.Restrict(sCriteria);
 oRestrictedItems.Sort("[Start]", false);
 oRestrictedItems.IncludeRecurrences = true;

 foreach (object obj in oRestrictedItems)
 {
    counter++;

    AppointmentItem appointment = obj as AppointmentItem;

    if (appointment == null || (appointment.Start.DayOfWeek == DayOfWeek.Saturday || 
       appointment.Start.DayOfWeek == DayOfWeek.Sunday))
       continue;

    if (appointment != null)
    {
       if (true)
       {
          DateTime endOfTheDay = new DateTime(appointment.Start.Date.Year, 
              appointment.Start.Date.Month, appointment.Start.Date.Day, 17, 0, 0);

          if (appointment.End.Hour < 8 || appointment.End.Hour > 17
             || (appointment.End.Hour - appointment.Start.Hour) > 5
             || appointment.End.Day - appointment.Start.Day > 0)
          {
             continue;
          }

          bool isOwnerMeeting = false;

          if (appointment.RequiredAttendees == null || 
		appointment.RequiredAttendees.Equals(string.Empty))
          {
             _meetingCountOwner++;
             isOwnerMeeting = true;
          }

          if (appointment.MeetingStatus == OlMeetingStatus.olMeeting ||
             appointment.MeetingStatus == OlMeetingStatus.olMeetingReceived ||
             appointment.RequiredAttendees == null ||
             appointment.RequiredAttendees.Equals(string.Empty))
          {
             _meetingCount++;

                      if (!isOwnerMeeting)
                _totalMeetingTime += appointment.End - appointment.Start;
          }
          if (appointment.Location != null && 
		(appointment.Location.Contains("Live Meeting") ||
             appointment.Location.Contains("LiveMeeting") ||
             appointment.Location.Contains("livemeeting") ||
             appointment.Location.Contains("live meeting")))
             _livmeetingCount++;
       }
    }
 }
 return appItems;
}

This case is also looking for his live meetings and accepted meetings. We can use this routine in other folders too by checking their periodical background. For example, getting featured Appointments, Tasks and Mails like below:

C#
public List<Outlook.AppointmentItem> GetFeaturedAppointments()
 {
 Outlook.MAPIFolder mpiFolder = 
    Application.GetNamespace("MAPI").GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
 var appItems = new List<Outlook.AppointmentItem>();
 foreach (object obj in mpiFolder.Items)
 {
    AppointmentItem appointment = obj as AppointmentItem;
    if (appointment != null)
    {
       if (appointment.Start > DateTime.Now - new TimeSpan(0, 30, 0))
          appItems.Add(appointment);
    }
 }
 return appItems;
 }

Also, we can find out the current user’s address. This is more important than I want to share:

C#
private string GetCurrentUserAddress()
 {
 try
 {
    Outlook.AddressEntry ae = Application.Session.CurrentUser.AddressEntry;
    switch (Application.Session.CurrentUser.DisplayType)
    {
       case (Outlook.OlDisplayType.olDistList):
          {
             ae = Application.Session.CurrentUser.AddressEntry;
             foreach (Outlook.AddressEntry aEnt in ae.Members)
             {
                if (aEnt.DisplayType != Outlook.OlDisplayType.olDistList && 
                    aEnt.DisplayType != Outlook.OlDisplayType.olPrivateDistList)
                {
                   string smtp = aEnt.GetExchangeUser().PrimarySmtpAddress;
                   return smtp;
             }
             }
          } break;
       case (Outlook.OlDisplayType.olPrivateDistList):
          {
             ae = Application.Session.CurrentUser.AddressEntry;
                   foreach (Outlook.AddressEntry aEnt in ae.Members)
             {
                if (aEnt.DisplayType != Outlook.OlDisplayType.olDistList && 
                    aEnt.DisplayType != Outlook.OlDisplayType.olPrivateDistList)
                {
                   string smtp = aEnt.Address;
                   return smtp;
                }
             }

          } break;
       case (Outlook.OlDisplayType.olUser):
          {
             string smtp = "";
             ae = Application.Session.CurrentUser.AddressEntry;
             if (ae.GetExchangeUser() == null)
             {
                smtp = ae.Address;
                return smtp;
             }
             else
             {
             smtp = ae.GetExchangeUser().PrimarySmtpAddress;
                return smtp;
             }
          } 
       default:
          {
             string smtp = "";
             ae = Application.Session.CurrentUser.AddressEntry;
             if (ae.GetExchangeUser() == null)
             {
                smtp = ae.Address;
             return smtp;
             }
             else
             {
                smtp = ae.GetExchangeUser().PrimarySmtpAddress;
                return smtp;
             }
          } 
    }
    return "";
 }
 catch (System.Exception ex)
 {
    throw ex;
 }
}

    public List<Outlook.TaskItem> GetFeaturedTasks()
    {
 Outlook.MAPIFolder mpiFolder = Application.GetNamespace("MAPI").
		GetDefaultFolder(OlDefaultFolders.olFolderTasks);
 var taskItems = new List<Outlook.TaskItem>();
 foreach (object obj in mpiFolder.Items)
 {
    TaskItem task = obj as TaskItem;
    if (task != null)
    {
       taskItems.Add(task);
    }
 }
 return taskItems;
    }

    public List<Outlook.MailItem> GetFeaturedMails()
    {
 Outlook.MAPIFolder mpiFolder = Application.GetNamespace
		("MAPI").GetDefaultFolder(OlDefaultFolders.olFolderSentMail);
 var mailItems = new List<Outlook.MailItem>();
 foreach (object obj in mpiFolder.Items)
 {
    MailItem mail = obj as MailItem;
    if (mail != null)
    {
       mailItems.Add(mail);
    }
 }
 return mailItems;
}

Version and Op. System Detection

The detection of the Op. System is out from this article’s target but I want to show you how you can detect this AddIn’s version and how we can write an AddIn according to other Op. Systems and according to other versions of the office. I will show Op. System detection routine before as below:

C#
private string FindVersion()
{
System.OperatingSystem osInfo = System.Environment.OSVersion;
string operatingSystem = "Unknown";
switch (osInfo.Platform)
{
   case System.PlatformID.Win32Windows:
      // Current OS is Windows - can be Windows95, 98 or ME
      switch (osInfo.Version.Minor)
   {
         case 0:
            operatingSystem = "Windows 95";
            break;
         case 10:
            operatingSystem = "Windows 98";
            break;
         case 90:
            operatingSystem = "Windows Me";
            break;
      }

      break;

   case System.PlatformID.Win32NT:
      // Current OS is Windows NT, 2000 or XP
      switch (osInfo.Version.Major)
      {
         case 3:
            operatingSystem = "Windows NT 3.51";
            break;
         case 4:
            operatingSystem = "Windows NT 4.0";
            break;
         case 5:
            if (osInfo.Version.Minor == 0)
               operatingSystem = "Windows 2000";
            else
               operatingSystem = "XP";
            break;
         case 6:
            operatingSystem = "Win7";
            break;
      }
      break;
}

return operatingSystem;
}

When we have got the system knowledge, then we can write any opportunities according to its properties. Anyway, the real important point here is the Version detection which I have prepared like below:

C#
string version = ((Microsoft.Office.Interop.Outlook.ApplicationClass)(((
    Microsoft.Office.Interop.Outlook.InspectorClass)

(_inspector)).Application)).Version;

int preVer = Convert.ToInt32(version.Substring(0, 2));

While preVer indicates 12 then office version is 2007, and when preVer indicates 12 then office version is 2007.

I was taught from this work that Microsoft Office 2007 Sp1 has a hot fix for Office 2007 object model’s Close and Save events support. Even Office 2010 does not have this opportunity yet.

Views

Views are providing customized screen and action management in Outlook. User can make settings from tool menu, but I want to prepare this feature programmatically in C#.

C#
private void CreateCustomAksiyonViewIfNotExist()
{
Application.ActiveExplorer().CurrentFolder.CustomViewsOnly = true;
Outlook.View lastView = Application.ActiveExplorer().CurrentFolder.CurrentView;
Outlook.View newView = null;
try
{
   bool isthere = false;
   Application.ActiveExplorer().NavigationPane.CurrentModule =
       Application.ActiveExplorer().NavigationPane.Modules[4];
   foreach (Outlook.View view in Application.ActiveExplorer().CurrentFolder.Views)
   {
      if (view.Name.Equals("Actions"))
         isthere = true;
   }
   if (!isthere)
   {
      newView = Application.ActiveExplorer().CurrentFolder.Views.Add("Actions",
      Outlook.OlViewType.olTableView,
      Outlook.OlViewSaveOption.olViewSaveOptionThisFolderEveryone);
      newView.Filter = "\"urn:schemas:httpmail:subject\" LIKE '% Actions %'";
      newView.Save();
      newView.Apply();
   }
}
catch (System.ArgumentException ex)
{
   MessageBox.Show(ex.Message);
   return;
}

Application.ActiveExplorer().NavigationPane.CurrentModule =
       Application.ActiveExplorer().NavigationPane.Modules[1];
}

Rules

Rules look like Views as a user customization but the Rules are relying on just actions and special contents when actions are released.

C#
void CreateActionRule()
{
Rules ruless = this.Application.Session.DefaultStore.GetRules();
for (int k = 1; k < ruless.Count; k++)
{
   if (ruless[k].Name.Equals("ActionAndDecissionRule"))
      return;
}

Outlook.MAPIFolder inbox = this.Application.Session.GetDefaultFolder(
    Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
inbox.Folders.Add("Aksiyon&Kararlar",
    Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
Outlook.MAPIFolder targetfolder = inbox.Folders["Aksiyon&Kararlar"];

Rules rules = this.Application.Session.DefaultStore.GetRules();
Outlook.Rule rule = rules.Create("ActionAndDecissionRule",
Microsoft.Office.Interop.Outlook.OlRuleType.olRuleReceive);

Outlook.TextRuleCondition sub = rule.Conditions.Body;
sub.Enabled = true;
sub.Text = new string[] { "ToplantisiKararlari-iyitoplantiKontrol" };

Outlook.MoveOrCopyRuleAction movecopy = rule.Actions.MoveToFolder;
movecopy.Enabled = true;
movecopy.Folder = targetfolder;

rule.Execute(true, inbox, false,
Outlook.OlRuleExecuteOption.olRuleExecuteUnreadMessages);
rules.Save(false);
}

Conclusion

In conclusion, I have researched many documents and I have not found enough information on this subject and there is no way to get a free book in this field. I am sure this information will be useful when someone wants to write an AddIn.

Annexes

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)