title: Outlook Interop - Read Calendars And Check for Private Appointments
body: <p>So I'm working on an app that will be able to read the outlook calendars for a set of individuals and build an itinerary for them.  I've got it pretty much working except that when I scrape a user's calendar, I'm not getting any information on the events they have marked as private. </p>
  
  <p>Let me make it clear that I'm not trying to peer into a user's calendar and read their darkest secret appointment titles, but I would still like to be able to show that this person is unavailable during that time.  For example in Outlook proper it just shows as "Private Appointment" - which is exactly what I want to be able to do in my app. </p>
  
  <p>Here's the code I've got for scraping the user's calendar:</p>
  
  <pre><code>    private Calendar CreateCalendar(String User_Name, String Initials, DateTime Week)
      {
          string filter = "[Start] &gt;= '"
              + Week.ToString("g")
              + "' AND [End] &lt;= '"
              + Week.AddDays(7).ToString("g") + "'";
  
          Microsoft.Office.Interop.Outlook.Application App = new Microsoft.Office.Interop.Outlook.Application();
          Microsoft.Office.Interop.Outlook.NameSpace mapiNamespace = App.GetNamespace("MAPI");
  
          //Resolve the person whose calendar We're trying to read.
          Outlook.Recipient rm = App.Session.CreateRecipient(User_Name);
          if (rm.Resolve())
          {
              try
              {
                  Outlook.Folder calFolder = App.Session.GetSharedDefaultFolder(rm, Outlook.OlDefaultFolders.olFolderCalendar) as Outlook.Folder;
                  Outlook.Items CalItems = calFolder.Items;
                  CalItems.IncludeRecurrences = true;
                  CalItems.Sort("[Start]", Type.Missing);
                  //Search for Items within the pre-defined time range.
  
                  Outlook.Items restrictItems = CalItems.Restrict(filter);
                  if (restrictItems.Count == 0)
                  {
                      Debug.Print("No Items Found");
                      return new Calendar(User_Name, Initials);
                  }
                  else
                  {
                      //Create our internal representation of their calendar, for use elsewhere.
                      Calendar cal = new Calendar(User_Name, Initials);
                      Outlook.AppointmentItem i = (Outlook.AppointmentItem)restrictItems.GetFirst();
  
                      do
                      {
                          cal.AddAppointment(i.Subject, i.Start, i.End);
                          i = restrictItems.GetNext();
                      } while (i != null);
  
                      App = null;
                      mapiNamespace = null;
                      return cal;
                  }
              }
              catch (Exception ex)
              {
                  App = null;
                  mapiNamespace = null;
                  throw new AccessViolationException(User_Name + " was resolved but could not access their calendar.  Have they set you up as a delegate?", ex);
              }
          }
          else
              throw new AccessViolationException("The name " + User_Name + " was not resolved, make sure their name in the RM List is spelled correctly. If you can enter their name as a recipient in an outlook mail message and it resolves correctly when you click 'Check Names', then it should work!");
      }
  </code></pre>
  
  <p>I'm not sure if private events are contained in the same "Folder" in outlook's data structures, so maybe I'm just not looking in the right spot? </p>
  
  <p>I've been having trouble googling this because "private" is a reserved word in C# that basically hits on every single post with code and a function declaration in it.  Hopefully you guys will be more helpful.</p>
  
  <p>Thanks!</p>