none
Outlook stops receiving when using Interop

    Question

  • I'm working on a new application and am trying to read in a user's appointments from Outlook and display them in the application.  For the most part I got this working, however I am coming across issues when a user has both my application and Outlook opened at the same time.

    When Outlook is opened first, my application will use the Outlook process that is already started and that works fine.  However if my application is opened first, and then Outlook is opened, Outlook is not able to receive new emails when I click the send/receive all button (but can send them) until it is restarted.  In my app, I don't close or release the Outlook.Application object until the app is closed - I want to leave it open so I can poll for new appointments without having to re-instantiate the Outlook.Application.

    Here is the code I am using to read in the appointments:

       public class MainDashBoardViewModel : ViewModelBase
        {
            private static object syncRoot = new Object();
    
            private static volatile Outlook.Application oAppInstance = null;
            public static Outlook.Application OApp
            {
                get
                {
                    if (oAppInstance == null)
                    {
                        lock (syncRoot)
                        {
                            if (oAppInstance == null)
                            {
                                if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
                                {
                                    oAppInstance = (Outlook.Application)Marshal.GetActiveObject("Outlook.Application");
                                }
                                else
                                {
                                    oAppInstance = new Outlook.Application();
                                }
                            }
                        }
                    }
    
                    return oAppInstance;
                }
            }
    
           public void GetAppointmentsInRange()
            {
                Outlook.NameSpace oNS = OApp.GetNamespace("MAPI");
                oNS.Logon("", "", Missing.Value, Missing.Value);
    
                Outlook.Folder calFolder = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar) as Outlook.Folder;
    
                DateTime start = DateTime.Now;
                DateTime end = start.AddDays(5);
    
                string filter = "[Start] >= '" + start.ToString("g") + "' AND [End] <= '" + end.ToString("g") + "'";
    
                Outlook.Items restrictItems = null;
    
                try
                {
                    Outlook.Items calItems = calFolder.Items;
                    calItems.IncludeRecurrences = true;
                    calItems.Sort("[Start]", Type.Missing);
                    restrictItems = calItems.Restrict(filter);
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message + e.StackTrace);
                }
    
                foreach(Outlook.AppointmentItem item in restrictItems)
                    AddDataToAppointments(item);
    
                oNS.Logoff();
            }
        }
    Does anyone know how to fix this, or do I just have to release the Outlook.Application instance everytime I read the appointments in?

    Friday, December 07, 2012 9:13 PM

Answers

  • I changed a few things and tested the code as a Windows Forms project.
     
     
    The code I left alone is GetAppointmentsInRange(), AddDataToAppointments(), the definitions of AppointmentCollection and Appointment, and the locals "appointments" and "Appointments".
     
    I added code to set NameSpace depending on how Outlook is started, and to display an Outlook UI if the code starts Outlook. I removed the "volatile" keywords as Outlook object model objects never should be referenced from another thread.
     
    With the changes I made I cannot repro the problem of receiving mail when the standalone code starts Outlook. I can press Send/Receive All and get test emails I sent to my dog's main email account.
     
    Here is my test code. The first class is in Program.cs, for the Windows Forms code startup:
     

    namespace WindowsFormsApplication2

    {

    static class Program

    {

    /// <summary>

    /// The main entry point for the application.

    /// </summary>

    [STAThread]

    static void Main()

    {

    Application.EnableVisualStyles();

    Application.SetCompatibleTextRenderingDefault(false);

    Application.Run(new Form1());

    }

    }

    }

    The remainder of the test code is in Form1.cs. I'll show the form startup code as well as the part of the MainDashBoardViewModel class I changed:
     

    using System;

    using System.Collections.Generic;

    using System.Collections.ObjectModel;

    using System.ComponentModel;

    using System.Data;

    using System.Drawing;

    using System.Linq;

    using System.Text;

    using System.Windows.Forms;

    using Outlook = Microsoft.Office.Interop.Outlook;

    using System.Runtime.InteropServices;

    using System.Diagnostics;

    using System.Reflection;

    namespace WindowsFormsApplication2

    {

    public partial class Form1 : Form

    {

    public Form1()

    {

    InitializeComponent();

    MainDashBoardViewModel model = new MainDashBoardViewModel();

    model.GetAppointmentsInRange();

    }

    }

    public class MainDashBoardViewModel

    {

    private static bool startedByUs = false;

    private static object syncRoot = new Object();

    //private static volatile Outlook.Application oAppInstance = null;

    private static Outlook.Application oAppInstance = null;

    private static object syncRoot2 = new Object();

    //private static volatile Outlook.NameSpace oNSInstance = null;

    private static Outlook.NameSpace oNSInstance = null;

    public static Outlook.Application OApp

    {

    get

    {

    if (oAppInstance == null)

    {

    lock (syncRoot)

    {

    if (oAppInstance == null)

    {

    if (Process.GetProcessesByName("OUTLOOK").Count() > 0)

    {

    oAppInstance = (Outlook.Application)Marshal.GetActiveObject("Outlook.Application");

    startedByUs = false;

    }

    else

    {

    oAppInstance = new Outlook.Application();

    startedByUs = true;

    }

    }

    }

    }

    return oAppInstance;

    }

    }

    public static Outlook.NameSpace oNS

    {

    get

    {

    if (oNSInstance == null)

    {

    lock (syncRoot2)

    {

    if (oNSInstance == null)

    {

    oNSInstance = OApp.GetNamespace("MAPI");

    if (startedByUs)

    {

    //oNS.Logon("", "", Missing.Value, Missing.Value);

    oNSInstance.Logon("", "", Missing.Value, Missing.Value);

    Outlook.Folder folder = oNSInstance.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) as Outlook.Folder;

    if (oAppInstance.Explorers.Count == 0)

    {

    oAppInstance.Explorers.Add(folder, Outlook.OlFolderDisplayMode.olFolderDisplayNormal);

    oAppInstance.Explorers[1].Activate();

    }

    Marshal.ReleaseComObject(folder);

    folder = null;

    }

    else

    {

    oNSInstance = OApp.Session;

    }

    }

    }

    }

    return oNSInstance;

    }

    }

    // unmodified code here.

    } // end of class MainDashBoardViewModel


    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "Bulleyeless" <=?utf-8?B?QnVsbGV5ZWxlc3M=?=> wrote in message news:f5e9563f-5dbc-4ef0-8ecf-80ae9b03a602...

    AddDataToAppointments just copies some information from the outlook item into my own custom class that I need to data bind to the gui.  Here is the corresponding code, it is in the same class as the above Interop code.

            private AppointmentCollection appointments = new AppointmentCollection();
            public AppointmentCollection Appointments 
            { 
                get
                {
                    return appointments;
                }
                set
                {
                    appointments = value;
                }
            }
    
            private void AddDataToAppointments(Outlook.AppointmentItem item)
            {
                Appointment app = new Appointment();
                app.Start = item.Start;
                app.Finish = item.End;
                app.Subject = item.Subject;
                app.Location = item.Location;
                app.Organizer = item.Organizer;
                Appointments.Add(app);
            }
        }
    
    

    And here is the code for the Appointment and AppointmentCollection classes

      public class Appointment
        {
            public DateTime Start { get; set; }
            public DateTime Finish { get; set; }
    
            public string Subject { get; set; }
            public string Location { get; set; }
            public string Organizer { get; set; }
            public string DateFormat 
            { 
                get
                {
                    string str = Start.DayOfWeek.ToString() + " " + Start.Date.ToShortDateString();
                    return str;
                }
            }
            public string TimeFormat
            {
                get
                {
                    return string.Format("{0}-{1}", FormatTimeString(Start), FormatTimeString(Finish));
                }
            }
    
            public string LocationOrganizerFormat
            {
                get
                {
                    return string.Format("{0};{1}", Location, Organizer);
                }
            }
    
            public override string ToString()
            {
                string str = ("Start: " + Start + ", Finish: " + Finish + ", Subject: " + Subject + ", Location: " + Location + ", Organizer: " + Organizer);
                return str;
            }
    
            private static string FormatTimeString(DateTime dateTime)
            {
                return string.Format("{0:hh:mmtt}", dateTime);
            }
        }
    
        public class AppointmentCollection : ObservableCollection<Appointment>
        {
           
        }

    Thanks for looking into this.


    Ken Slovak MVP - Outlook
    Wednesday, December 12, 2012 6:44 PM
  • That different Outlook icon and tooltip are to be expected if outside standalone code is starting Outlook. I got that also with my test code. However, I did not have any problems in receiving emails with the code running in either configuration (Outlook started first or my test code started first).
     
    I sent out 5 emails at intervals to my dog's domain email address for both configurations.
     
    Running under his email account, I then received the emails both by automatic send/receive and by clicking the Send/Receive button and by pressing F9.

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "Bulleyeless" <=?utf-8?B?QnVsbGV5ZWxlc3M=?=> wrote in message news:ea2c36fd-bda7-47a2-b10a-fd9ab6087dab...

    I just copied and pasted your code into my own Windows Forms test application, but I'm still having the same issue.  When Outlook is opened from my standalone code the application opens as expected, and the outlook icon shows up in my taskbar, but it says "Another program is using Outlook. To disconnect programs and exit Outlook, click the Outlook icon and then click Exit Now."  This message does not show up when I have Outlook running first and then connect to the running application.

    The weird thing is I can send emails and change my calendar and stuff, but I just can't receive emails.  So maybe it is a permissions thing, like Outlook doesn't trust my app to open it up and receive emails or something. Anyways, I guess I'll just have to deal with it for the time being.

    Thanks for all of your input, at least I've been able to eliminate some of the reasons this could be happening.


    Ken Slovak MVP - Outlook
    Thursday, December 13, 2012 2:48 PM
  • Are you able to open a support incident for this?
     
    If your company has an MSDN subscription you have support incidents available, and even if you open a paid incident if it proves to be a bug the cost will be reimbursed or waived.

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "Bulleyeless" <=?utf-8?B?QnVsbGV5ZWxlc3M=?=> wrote in message news:868a9506-7c60-40ab-8236-83feafc0871b...

    One of my co-workers was able to determine that this issue only happens when you are connected to an exchange server and outlook has Use Cached Exchange Mode checked in the Account Settings.  When you use online only mode it works just fine.

    However I'm not the administrator of Exchange/Outlook at my company, so I cannot force people to use these settings.  Maybe this information could help you reproduce the issue.


    Ken Slovak MVP - Outlook
    Thursday, December 13, 2012 6:07 PM

All replies

  • why do you call Logoff on Namespace object? comment out calls to Logon and Logoff and try again.
    Saturday, December 08, 2012 6:14 AM
  • Logon() would be needed if the connection to Outlook is out of process (standalone application). Logoff() would be a problem.

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "DamianD" <=?utf-8?B?RGFtaWFuRA==?=> wrote in message news:775872bb-60be-444d-bb51-b61e91f0cc94...
    why do you call Logoff on Namespace object? comment out calls to Logon and Logoff and try again.

    Ken Slovak MVP - Outlook
    Monday, December 10, 2012 2:14 PM
  • That still didn't work.  I tried commenting out just Logoff(), and then both Logon() and Logoff() and it gave me the exact same results.  I actually originally added the calls to Logon() and Logoff() to try to fix this problem, and I forgot to take them out when I posted the code.
    Monday, December 10, 2012 3:52 PM
  • Are you running under the same permissions with Outlook and your standalone code? Are you releasing all your Outlook objects in your code?

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "Bulleyeless" <=?utf-8?B?QnVsbGV5ZWxlc3M=?=> wrote in message news:a7204c4d-b9ba-4628-837a-6f4714035d12...
    That still didn't work.  I tried commenting out just Logoff(), and then both Logon() and Logoff() and it gave me the exact same results.  I actually originally added the calls to Logon() and Logoff() to try to fix this problem, and I forgot to take them out when I posted the code.

    Ken Slovak MVP - Outlook
    Monday, December 10, 2012 3:56 PM
  • I believe I am running them both under the same permissions.  I checked the processes in Task Manager and they were both running under my user name and I didn't right click to "Run as Administrator" or anything like that.  Are there any other permission related things I should check?

    As for releasing the Outlook objects I don't want to release them until the application exits.  I would like to keep the Outlook.Application open so I can poll for new appointments at certain intervals and not have to keep restarting it. Maybe that isn't a good way to go about it though, I'm not sure.

    Monday, December 10, 2012 5:10 PM
  • When I mentioned releasing items I didn't mean to release the Outlook.Application object. You should however release everything in GetAppointmentsInRange() and any other methods where you're using the Outlook object model.
     
    You also should change your for loop as you can't release objects in a foreach loop:
     
    foreach(Outlook.AppointmentItem item in restrictItems)
    Outlook.AppointmentItem item = null;
    for (int i = 1; i <= restrictItems.Count; i++)
    {
        item = restrictItems[i];
        // do whatever
        Marshal.ReleaseComObject(item);
        item = null;
    }
     
    What version of Outlook is this? What environment is the code running in, desktop or service or ...?
     
    I would also move the NameSpace declaration to a class level to keep it alive, and only log in once.

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "Bulleyeless" <=?utf-8?B?QnVsbGV5ZWxlc3M=?=> wrote in message news:81d7b3b5-ac7e-4a50-93d3-d85193d0f30d...

    I believe I am running them both under the same permissions.  I checked the processes in Task Manager and they were both running under my user name and I didn't right click to "Run as Administrator" or anything like that.  Are there any other permission related things I should check?

    As for releasing the Outlook objects I don't want to release them until the application exits.  I would like to keep the Outlook.Application open so I can poll for new appointments at certain intervals and not have to keep restarting it. Maybe that isn't a good way to go about it though, I'm not sure.


    Ken Slovak MVP - Outlook
    Tuesday, December 11, 2012 3:07 PM
  • I made the NameSpace a member variable instead of a local variable, and released all of the local COM objects I was using, but I'm still having the same problem.

    I'm using Outlook 2010 and running on Windows 7 Professional 64-bit, and my app is a WPF desktop application using .NET 4.0.

    Here is the updated source code with the changes you suggested:

        public class MainDashBoardViewModel : ViewModelBase
        {
            private static object syncRoot = new Object();
    
            private static volatile Outlook.Application oAppInstance = null;
            public static Outlook.Application OApp
            {
                get
                {
                    if (oAppInstance == null)
                    {
                        lock (syncRoot)
                        {
                            if (oAppInstance == null)
                            {
                                if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
                                {
                                    oAppInstance = (Outlook.Application)Marshal.GetActiveObject("Outlook.Application");
                                }
                                else
                                {
                                    oAppInstance = new Outlook.Application();
                                }
                            }
                        }
                    }
    
                    return oAppInstance;
                }
            }
    
            private static object syncRoot2 = new Object();
    
            private static volatile Outlook.NameSpace oNSInstance = null;
            public static Outlook.NameSpace oNS
            {
                get
                {
                    if (oNSInstance == null)
                    {
                        lock (syncRoot2)
                        {
                            if (oNSInstance == null)
                            {
                                oNSInstance = OApp.GetNamespace("MAPI");
                                oNS.Logon("", "", Missing.Value, Missing.Value);
                            }
                        }
                    }
                    return oNSInstance;
                }
            }
    
           public void GetAppointmentsInRange()
            {
                Outlook.Folder calFolder = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar) as Outlook.Folder;
    
                DateTime start = DateTime.Now;
                DateTime end = start.AddDays(5);
    
                string filter = "[Start] >= '" + start.ToString("g") + "' AND [End] <= '" + end.ToString("g") + "'";
    
                Outlook.Items restrictItems = null;
    
                try
                {
                    Outlook.Items calItems = calFolder.Items;
                    calItems.Sort("[Start]", Type.Missing);
                    calItems.IncludeRecurrences = true;
                    restrictItems = calItems.Restrict(filter);
                    Marshal.ReleaseComObject(calItems);
                    calItems = null;
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message + e.StackTrace);
                }
    
                Outlook.AppointmentItem item = null;
                for (int i = 1; i <= restrictItems.Count; i++)
                {
                    item = restrictItems[i];
    
                    // This is necessary because if you have recurring appointments with no end date restrictItems.Count will be infinity 
                    // and cannot control the loop correctly
                    if (item == null)
                        break;
    
                    AddDataToAppointments(item);
                    Marshal.ReleaseComObject(item);
                    item = null;
                }
    
                Marshal.ReleaseComObject(restrictItems);
                Marshal.ReleaseComObject(calFolder);
            }
    }

    Tuesday, December 11, 2012 5:01 PM
  • I've heard of a a lot of problems with the combination of WPF and Outlook object model managed code. I avoid using WPF completely when using Outlook code. Can you set up a simple test program that uses the same code you have now and run that in a Windows Form project as a test to see if the problem travels to that project or is exclusive to the WPF project?

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "Bulleyeless" <=?utf-8?B?QnVsbGV5ZWxlc3M=?=> wrote in message news:ff3c9cc8-1631-4be7-b68a-a6c1183349a1...

    I made the NameSpace a member variable instead of a local variable, and released all of the local COM objects I was using, but I'm still having the same problem.

    I'm using Outlook 2010 and running on Windows 7 Professional 64-bit, and my app is a WPF desktop application using .NET 4.0.

    Here is the updated source code with the changes you suggested:

        public class MainDashBoardViewModel : ViewModelBase
        {
            private static object syncRoot = new Object();
    
            private static volatile Outlook.Application oAppInstance = null;
            public static Outlook.Application OApp
            {
                get
                {
                    if (oAppInstance == null)
                    {
                        lock (syncRoot)
                        {
                            if (oAppInstance == null)
                            {
                                if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
                                {
                                    oAppInstance = (Outlook.Application)Marshal.GetActiveObject("Outlook.Application");
                                }
                                else
                                {
                                    oAppInstance = new Outlook.Application();
                                }
                            }
                        }
                    }
    
                    return oAppInstance;
                }
            }
    
            private static object syncRoot2 = new Object();
    
            private static volatile Outlook.NameSpace oNSInstance = null;
            public static Outlook.NameSpace oNS
            {
                get
                {
                    if (oNSInstance == null)
                    {
                        lock (syncRoot2)
                        {
                            if (oNSInstance == null)
                            {
                                oNSInstance = OApp.GetNamespace("MAPI");
                                oNS.Logon("", "", Missing.Value, Missing.Value);
                            }
                        }
                    }
                    return oNSInstance;
                }
            }
    
           public void GetAppointmentsInRange()
            {
                Outlook.Folder calFolder = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar) as Outlook.Folder;
    
                DateTime start = DateTime.Now;
                DateTime end = start.AddDays(5);
    
                string filter = "[Start] >= '" + start.ToString("g") + "' AND [End] <= '" + end.ToString("g") + "'";
    
                Outlook.Items restrictItems = null;
    
                try
                {
                    Outlook.Items calItems = calFolder.Items;
                    calItems.Sort("[Start]", Type.Missing);
                    calItems.IncludeRecurrences = true;
                    restrictItems = calItems.Restrict(filter);
                    Marshal.ReleaseComObject(calItems);
                    calItems = null;
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message + e.StackTrace);
                }
    
                Outlook.AppointmentItem item = null;
                for (int i = 1; i <= restrictItems.Count; i++)
                {
                    item = restrictItems[i];
    
                    // This is necessary because if you have recurring appointments with no end date restrictItems.Count will be infinity 
                    // and cannot control the loop correctly
                    if (item == null)
                        break;
    
                    AddDataToAppointments(item);
                    Marshal.ReleaseComObject(item);
                    item = null;
                }
    
                Marshal.ReleaseComObject(restrictItems);
                Marshal.ReleaseComObject(calFolder);
            }
    }


    Ken Slovak MVP - Outlook
    Tuesday, December 11, 2012 5:08 PM
  • I made a test program in Windows forms and used the exact same Outlook code, and I still experienced the same issue.  So it looks like this issue isn't exclusive to WPF.
    Tuesday, December 11, 2012 7:17 PM
  • What does AddDataToAppointments(item) do? It doesn't persist the Outlook item, does it?
     
    Show that code and anything related so I can test, I want to try to repro this here.


    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "Bulleyeless" <=?utf-8?B?QnVsbGV5ZWxlc3M=?=> wrote in message news:49726ced-fe0d-4a43-b915-7ec43100cf20...
    I made a test program in Windows forms and used the exact same Outlook code, and I still experienced the same issue.  So it looks like this issue isn't exclusive to WPF.

    Ken Slovak MVP - Outlook
    Tuesday, December 11, 2012 10:05 PM
  • Oh yeah, one other thing.

    If you're grabbing a running Outlook session in your startup code, don't do a logon to NameSpace, use the existing session:

    // part where you get the running Process

    oNS = oAppInstance.Session;

    // part where you use new Outlook.Application

    // do the logon here

    And maintain flags that tell you if you started Outlook or it was running. That way you know if you'd want to use Application.Quit() to close Outlook after your code runs.


    Ken Slovak MVP - Outlook

    Tuesday, December 11, 2012 10:13 PM
  • AddDataToAppointments just copies some information from the outlook item into my own custom class that I need to data bind to the gui.  Here is the corresponding code, it is in the same class as the above Interop code.

            private AppointmentCollection appointments = new AppointmentCollection();
            public AppointmentCollection Appointments 
            { 
                get
                {
                    return appointments;
                }
                set
                {
                    appointments = value;
                }
            }
    
            private void AddDataToAppointments(Outlook.AppointmentItem item)
            {
                Appointment app = new Appointment();
                app.Start = item.Start;
                app.Finish = item.End;
                app.Subject = item.Subject;
                app.Location = item.Location;
                app.Organizer = item.Organizer;
                Appointments.Add(app);
            }
        }
    
    

    And here is the code for the Appointment and AppointmentCollection classes

      public class Appointment
        {
            public DateTime Start { get; set; }
            public DateTime Finish { get; set; }
    
            public string Subject { get; set; }
            public string Location { get; set; }
            public string Organizer { get; set; }
            public string DateFormat 
            { 
                get
                {
                    string str = Start.DayOfWeek.ToString() + " " + Start.Date.ToShortDateString();
                    return str;
                }
            }
            public string TimeFormat
            {
                get
                {
                    return string.Format("{0}-{1}", FormatTimeString(Start), FormatTimeString(Finish));
                }
            }
    
            public string LocationOrganizerFormat
            {
                get
                {
                    return string.Format("{0};{1}", Location, Organizer);
                }
            }
    
            public override string ToString()
            {
                string str = ("Start: " + Start + ", Finish: " + Finish + ", Subject: " + Subject + ", Location: " + Location + ", Organizer: " + Organizer);
                return str;
            }
    
            private static string FormatTimeString(DateTime dateTime)
            {
                return string.Format("{0:hh:mmtt}", dateTime);
            }
        }
    
        public class AppointmentCollection : ObservableCollection<Appointment>
        {
           
        }

    Thanks for looking into this.

    Tuesday, December 11, 2012 10:17 PM
  • I changed a few things and tested the code as a Windows Forms project.
     
     
    The code I left alone is GetAppointmentsInRange(), AddDataToAppointments(), the definitions of AppointmentCollection and Appointment, and the locals "appointments" and "Appointments".
     
    I added code to set NameSpace depending on how Outlook is started, and to display an Outlook UI if the code starts Outlook. I removed the "volatile" keywords as Outlook object model objects never should be referenced from another thread.
     
    With the changes I made I cannot repro the problem of receiving mail when the standalone code starts Outlook. I can press Send/Receive All and get test emails I sent to my dog's main email account.
     
    Here is my test code. The first class is in Program.cs, for the Windows Forms code startup:
     

    namespace WindowsFormsApplication2

    {

    static class Program

    {

    /// <summary>

    /// The main entry point for the application.

    /// </summary>

    [STAThread]

    static void Main()

    {

    Application.EnableVisualStyles();

    Application.SetCompatibleTextRenderingDefault(false);

    Application.Run(new Form1());

    }

    }

    }

    The remainder of the test code is in Form1.cs. I'll show the form startup code as well as the part of the MainDashBoardViewModel class I changed:
     

    using System;

    using System.Collections.Generic;

    using System.Collections.ObjectModel;

    using System.ComponentModel;

    using System.Data;

    using System.Drawing;

    using System.Linq;

    using System.Text;

    using System.Windows.Forms;

    using Outlook = Microsoft.Office.Interop.Outlook;

    using System.Runtime.InteropServices;

    using System.Diagnostics;

    using System.Reflection;

    namespace WindowsFormsApplication2

    {

    public partial class Form1 : Form

    {

    public Form1()

    {

    InitializeComponent();

    MainDashBoardViewModel model = new MainDashBoardViewModel();

    model.GetAppointmentsInRange();

    }

    }

    public class MainDashBoardViewModel

    {

    private static bool startedByUs = false;

    private static object syncRoot = new Object();

    //private static volatile Outlook.Application oAppInstance = null;

    private static Outlook.Application oAppInstance = null;

    private static object syncRoot2 = new Object();

    //private static volatile Outlook.NameSpace oNSInstance = null;

    private static Outlook.NameSpace oNSInstance = null;

    public static Outlook.Application OApp

    {

    get

    {

    if (oAppInstance == null)

    {

    lock (syncRoot)

    {

    if (oAppInstance == null)

    {

    if (Process.GetProcessesByName("OUTLOOK").Count() > 0)

    {

    oAppInstance = (Outlook.Application)Marshal.GetActiveObject("Outlook.Application");

    startedByUs = false;

    }

    else

    {

    oAppInstance = new Outlook.Application();

    startedByUs = true;

    }

    }

    }

    }

    return oAppInstance;

    }

    }

    public static Outlook.NameSpace oNS

    {

    get

    {

    if (oNSInstance == null)

    {

    lock (syncRoot2)

    {

    if (oNSInstance == null)

    {

    oNSInstance = OApp.GetNamespace("MAPI");

    if (startedByUs)

    {

    //oNS.Logon("", "", Missing.Value, Missing.Value);

    oNSInstance.Logon("", "", Missing.Value, Missing.Value);

    Outlook.Folder folder = oNSInstance.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) as Outlook.Folder;

    if (oAppInstance.Explorers.Count == 0)

    {

    oAppInstance.Explorers.Add(folder, Outlook.OlFolderDisplayMode.olFolderDisplayNormal);

    oAppInstance.Explorers[1].Activate();

    }

    Marshal.ReleaseComObject(folder);

    folder = null;

    }

    else

    {

    oNSInstance = OApp.Session;

    }

    }

    }

    }

    return oNSInstance;

    }

    }

    // unmodified code here.

    } // end of class MainDashBoardViewModel


    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "Bulleyeless" <=?utf-8?B?QnVsbGV5ZWxlc3M=?=> wrote in message news:f5e9563f-5dbc-4ef0-8ecf-80ae9b03a602...

    AddDataToAppointments just copies some information from the outlook item into my own custom class that I need to data bind to the gui.  Here is the corresponding code, it is in the same class as the above Interop code.

            private AppointmentCollection appointments = new AppointmentCollection();
            public AppointmentCollection Appointments 
            { 
                get
                {
                    return appointments;
                }
                set
                {
                    appointments = value;
                }
            }
    
            private void AddDataToAppointments(Outlook.AppointmentItem item)
            {
                Appointment app = new Appointment();
                app.Start = item.Start;
                app.Finish = item.End;
                app.Subject = item.Subject;
                app.Location = item.Location;
                app.Organizer = item.Organizer;
                Appointments.Add(app);
            }
        }
    
    

    And here is the code for the Appointment and AppointmentCollection classes

      public class Appointment
        {
            public DateTime Start { get; set; }
            public DateTime Finish { get; set; }
    
            public string Subject { get; set; }
            public string Location { get; set; }
            public string Organizer { get; set; }
            public string DateFormat 
            { 
                get
                {
                    string str = Start.DayOfWeek.ToString() + " " + Start.Date.ToShortDateString();
                    return str;
                }
            }
            public string TimeFormat
            {
                get
                {
                    return string.Format("{0}-{1}", FormatTimeString(Start), FormatTimeString(Finish));
                }
            }
    
            public string LocationOrganizerFormat
            {
                get
                {
                    return string.Format("{0};{1}", Location, Organizer);
                }
            }
    
            public override string ToString()
            {
                string str = ("Start: " + Start + ", Finish: " + Finish + ", Subject: " + Subject + ", Location: " + Location + ", Organizer: " + Organizer);
                return str;
            }
    
            private static string FormatTimeString(DateTime dateTime)
            {
                return string.Format("{0:hh:mmtt}", dateTime);
            }
        }
    
        public class AppointmentCollection : ObservableCollection<Appointment>
        {
           
        }

    Thanks for looking into this.


    Ken Slovak MVP - Outlook
    Wednesday, December 12, 2012 6:44 PM
  • I just copied and pasted your code into my own Windows Forms test application, but I'm still having the same issue.  When Outlook is opened from my standalone code the application opens as expected, and the outlook icon shows up in my taskbar, but it says "Another program is using Outlook. To disconnect programs and exit Outlook, click the Outlook icon and then click Exit Now."  This message does not show up when I have Outlook running first and then connect to the running application.

    The weird thing is I can send emails and change my calendar and stuff, but I just can't receive emails.  So maybe it is a permissions thing, like Outlook doesn't trust my app to open it up and receive emails or something. Anyways, I guess I'll just have to deal with it for the time being.

    Thanks for all of your input, at least I've been able to eliminate some of the reasons this could be happening.

    Wednesday, December 12, 2012 10:57 PM
  • That different Outlook icon and tooltip are to be expected if outside standalone code is starting Outlook. I got that also with my test code. However, I did not have any problems in receiving emails with the code running in either configuration (Outlook started first or my test code started first).
     
    I sent out 5 emails at intervals to my dog's domain email address for both configurations.
     
    Running under his email account, I then received the emails both by automatic send/receive and by clicking the Send/Receive button and by pressing F9.

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "Bulleyeless" <=?utf-8?B?QnVsbGV5ZWxlc3M=?=> wrote in message news:ea2c36fd-bda7-47a2-b10a-fd9ab6087dab...

    I just copied and pasted your code into my own Windows Forms test application, but I'm still having the same issue.  When Outlook is opened from my standalone code the application opens as expected, and the outlook icon shows up in my taskbar, but it says "Another program is using Outlook. To disconnect programs and exit Outlook, click the Outlook icon and then click Exit Now."  This message does not show up when I have Outlook running first and then connect to the running application.

    The weird thing is I can send emails and change my calendar and stuff, but I just can't receive emails.  So maybe it is a permissions thing, like Outlook doesn't trust my app to open it up and receive emails or something. Anyways, I guess I'll just have to deal with it for the time being.

    Thanks for all of your input, at least I've been able to eliminate some of the reasons this could be happening.


    Ken Slovak MVP - Outlook
    Thursday, December 13, 2012 2:48 PM
  • One of my co-workers was able to determine that this issue only happens when you are connected to an exchange server and outlook has Use Cached Exchange Mode checked in the Account Settings.  When you use online only mode it works just fine.

    However I'm not the administrator of Exchange/Outlook at my company, so I cannot force people to use these settings.  Maybe this information could help you reproduce the issue.

    Thursday, December 13, 2012 5:16 PM
  • Are you able to open a support incident for this?
     
    If your company has an MSDN subscription you have support incidents available, and even if you open a paid incident if it proves to be a bug the cost will be reimbursed or waived.

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "Bulleyeless" <=?utf-8?B?QnVsbGV5ZWxlc3M=?=> wrote in message news:868a9506-7c60-40ab-8236-83feafc0871b...

    One of my co-workers was able to determine that this issue only happens when you are connected to an exchange server and outlook has Use Cached Exchange Mode checked in the Account Settings.  When you use online only mode it works just fine.

    However I'm not the administrator of Exchange/Outlook at my company, so I cannot force people to use these settings.  Maybe this information could help you reproduce the issue.


    Ken Slovak MVP - Outlook
    Thursday, December 13, 2012 6:07 PM