1

I'm attempting to write an outlook-addin that reads appointments from a user's inbox and generates reminder emails 72 hours prior to the meeting. I learned how to do this by piecing together snippets from SO and the web, but I'm running into a few errors. I'm not sure I understand what's going on enough to even ask the correct questions, so please forgive my bumbling through this.

So, when I try to spoof the "Sender" using the code below, I get the following error:

"Generating server: MBX080-W3-CO-1.exch080.serverpod.net
josh.alcorn@crmpoint.net
Remote Server returned '550 5.6.2 STOREDRV.Submit; subscription not found'
Original message headers:
Received: from MBX080-W3-CO-1.exch080.serverpod.net ([10.224.117.52]) by
 MBX080-W3-CO-1.exch080.serverpod.net ([169.254.1.30]) with mapi id
 15.00.1044.021; Mon, 8 Jun 2015 08:28:25 -0700
MIME-Version: 1.0
Content-Type: text/plain
Date: Mon, 8 Jun 2015 08:28:25 -0700
X-MS-Exchange-Transport-FromEntityHeader: Hosted
Message-ID:
    <b8690284ffb04af794a676b8efdee58d@MBX080-W3-CO-1.exch080.serverpod.net>
Subject: This is the subject"

WHen I remove the sender code, it seems to be firing correctly for 2 of my test appointments, but throws a nullreferenceexception on the third. I can't seem to figure out how to use the debugger in conjunction with Outlook so I don't have much better information on that error. As for this issue, any advice on how to debug an Outlook 2013 addin in real-time would be tremendously appreciated. I've tried all the tricks I know.

using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Interop.Outlook;
using System.Windows.Forms;

//http://stackoverflow.com/questions/6425776/outlook-2010-how-to-get-a-list-of-all-appointments-including-recurrences
//https://www.add-in-express.com/creating-addins-blog/2013/06/10/outlook-calendar-appointment-meeting-items/
//http://www.sperrysoftware.com/outlook/email-reminders.asp
//myEmailAddress = this.ActiveExplorer().Session.CurrentUser.EmailAddress;
//Application.Session.CurrentUser.AddressEntry.Address
//https://www.add-in-express.com/creating-addins-blog/2013/06/10/outlook-calendar-appointment-meeting-items/#enumerate
//http://www.scrubly.com/blog/how-to-outlook/how-to-install-enable-and-disable-outlook-2013-add-ins/
//http://stackoverflow.com/questions/5472493/making-vsto-add-in-installable
//https://msdn.microsoft.com/en-us/library/cc442767.aspx#Download

namespace OutlookAddIn1
{
    public partial class ThisAddIn
    {
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        doStuff();
    }

    private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
    {
    }

    #region VSTO generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InternalStartup()
    {
        this.Startup += new System.EventHandler(ThisAddIn_Startup);
        this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
    }

    //https://msdn.microsoft.com/en-us/library/ms268866.aspx

    private void doStuff()
    {
        Thread.Sleep(120000); //120 seconds

        DateTime firstRun = DateTime.Now; //So we can check every 24 hours? Maybe once initially as well.
        DateTime lastRun = DateTime.Now;//.AddHours(1); //We're going to compare this to firstRun
        bool whileTrue = true;
        //int test = 0;
        try
        {
            while (whileTrue)
            {
                if (whileTrue == true)//(firstRun > lastRun.AddDays(1))
                {
                    Outlook.MAPIFolder calendarFolder =     Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalenda    r);
                    Outlook.Items outlookCalendarItems =        calendarFolder.Items;
                    outlookCalendarItems.IncludeRecurrences = false; //was true

                    List<Outlook.AppointmentItem> lst = new List<Outlook.AppointmentItem>();

                    foreach (Outlook.AppointmentItem item in outlookCalendarItems)
                    {
                        lst.Add(item);
                        //We can probably just handle logic in here without the second for loop that comes next
                    }

                    foreach (Outlook.AppointmentItem x in lst)
                    {
                        //http://stackoverflow.com/questions/16329581/getting-system-runtime-interopservices-comexception-error-in-server-side-generat
                        DateTime startDate = DateTime.Now.AddDays(1);
                        DateTime endDate = DateTime.Now.AddDays(5);
                        DateTime apptDate = x.Start;


                        if (x.Subject.ToLower().Contains("telos"))
                        {
                            MessageBox.Show("X: " + x.Start + "XYZ: " + x.Subject);

                            if (x.Start > startDate && x.Start < endDate)
                            {
                                Outlook.MailItem mailItem = (Outlook.MailItem)
                                    this.Application.CreateItem(Outlook.OlItemType.olMailItem);
                                //http://stackoverflow.com/questions/11223462/how-to-send-a-mail-using-microsoft-office-interop-outlook-mailitem-by-specifying
                                //Outlook.Recipient recipient = this.Application.Session.CreateRecipient("someone@example.com");
                                //mailItem.Sender = recipient.AddressEntry;
                                Outlook.Recipient recipTo =
                                    mailItem.Recipients.Add("someone@example.com");
                                recipTo.Type = (int)Outlook.OlMailRecipientType.olTo;
                                mailItem.Sender = (Outlook.AddressEntry)recipTo;
                                //Outlook.Account account = new Account();// Application.Session.Accounts["MyOtherAccount"];

                                //mailItem.SendUsingAccount = account;

                                mailItem.Subject = "This is the subject";
                                mailItem.To = Application.Session.CurrentUser.AddressEntry.Address; //"someone@example.com";
                                mailItem.Body = "This is the message.";
                                mailItem.Importance = Outlook.OlImportance.olImportanceLow;
                                mailItem.Display(false);
                                ((Outlook._MailItem)mailItem).Send();
                                //mailItem.Send();
                                /*
                                //Here we generate the email
                                Outlook.Application app = new Outlook.Application();
                                Microsoft.Office.Interop.Outlook.MailItem email = app.CreateItem((OlItemType.olMailItem));

                                Outlook.Recipient recipient = app.Session.CreateRecipient("someone@example.com");
                                email.Sender = recipient.AddressEntry;
                                email.Display(false);
                                email.Subject = "You have a new appointment";
                                email.To = Application.Session.CurrentUser.AddressEntry.Address; //Current email address.
                                email.Body = "This email was automatically generated to remind you have an upcoming appointment on: " + x.Start.ToString();
                                ((Outlook._MailItem)email).Send();
                                //email.Send();
                                //((Outlook._MailItem)mailItem).Send();
                                app.Quit();
                                 * */
                            }
                        }
                    }

                    lastRun = DateTime.Now;
                    whileTrue = false;
                }
                else
                {
                }
            }
        }
        catch (System.Exception e) //Microsoft.Office.Interop.Outlook.Exception e
        {
            MessageBox.Show(e.ToString());
        }



    }

    public void createContact()
    {
        Outlook.ContactItem newContact = (Outlook.ContactItem)
            this.Application.CreateItem(Outlook.OlItemType.olContactItem);
        try
        {
            newContact.FirstName = "Person";
            newContact.LastName = "LastName";
            newContact.Email1Address = "someone@example.com";
            newContact.Save();
            newContact.Display(true);
        }
        catch
        {
            MessageBox.Show("The new contact was not saved.");
        }
    }


    #endregion
}
}
Josh Alcorn
  • 158
  • 1
  • 17

1 Answers1

0

Running a time-consuming task in the Startup event handler is a good idea. The fact is that Outlook measures the time required for loading add-ins and may disable it automatically (if it takes a lot of time). See the Performance criteria for keeping add-ins enabled section in the What's new for Outlook 2013 developers article in MSDN for more information.

Also I'd suggest creating a log file and writing any action in the log. Thus, you will be aware what happens at runtime and what line of code generates an error.

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • Thank you very much Eugene. I'm not sure how the loading time has anything to do with my question so can you please elaborate for me? That wasn't meant to be flippant, btw. I just can't mentally connect the dots. I'll get started working on building a log file as well. – Josh Alcorn Jun 08 '15 at 18:59