none
Catch Outlook opening RRS feed

  • Question

  • Hi all!

    May be there is similar question on this forum but I have not found it.

    My program is watching new attachment actions on outlook.

    For realizing this watch I need to grab Outlook instance by Marshal.GetActiveObject. So I do.

    But Outlook is not always already opened. So I decided to make some timer to check if Outlook has been opened.

    And if it is opened I stop timer. This scenario doesn't seem complicated, but I faced some problems.

    If I run my application while Outlook is not opened and then open Outlook my timer didn't stops,

    until I switch between any applications in Windows. After switch Timer stops immediately.

    Where is my mistake?

    Here my code in C# Windows Forms Application (I have put Timer on the form) :

    public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                timer1.Start();
            }
            private void timer1_Tick(object sender, EventArgs e)
            {
                bool aErr = false;
                Object obj = null;
                try
                {
                    obj = Marshal.GetActiveObject("Outlook.Application");
                }
                catch (System.Exception ex)
                {
                    aErr = true;
                }
                if (false == aErr)
                {
                    timer1.Stop();
                    MessageBox.Show("success", "success");                
                }
                else
                    return;
            }        
        }

    Thank you in advance,

    Michael.

    Saturday, May 26, 2012 7:33 AM

Answers

All replies

  • Why not create an Outlook add-in? It will be loaded each time Outlook starts up.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.3 is now available!

    Saturday, May 26, 2012 3:24 PM
  • My application was already written outside Outlook and I have not thought that there could be any problems in this final step(
    Monday, May 28, 2012 2:19 PM
  • Hi Mikaell_A,

    Welcome to MSDN Forum.
    According to your description, I've developed a Windows Forms Application using code below.

    public partial class Form1 : Form
    {
        private static System.Timers.Timer timer1;
        public Form1()
        {
            InitializeComponent();
            timer1 = new System.Timers.Timer(1000); 
            //parameter set the timer1.Interval property to 1000
            timer1.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            timer1.Start();
        }
    
        private void OnTimedEvent(object sender, EventArgs e)
        {
                bool aErr = false;
                Object obj = null;
                try
                {
                    obj = Marshal.GetActiveObject("Outlook.Application");
                }
                catch (System.Exception ex)
                {
                    aErr = true;
                }
                if (false == aErr)
                {
                    timer1.Stop();
                    MessageBox.Show("Success", "Success");
                }
                else
                return;
        }
    }
    

    I have the code compiled firstly, then startup my Outlook and the timer works fine. Maybe your scenario is because you have set your timer1.Interval property to a big value.

    Hope it helps.

    Best Regards,
    Quist


    Quist Zhang [MSFT]
    MSDN Community Support | Feedback to us

    Tuesday, May 29, 2012 5:48 AM
    Moderator
  • Hi, Quist Zhang,

    thank you for answer. I have modified my code like in your sample (creating timer dynamically).

    I have the same result. If I do not switch between applications then nothing happens.

    May be I have not described it right way, so I describe situation again.

    I run my application with outlook closed. Then I run outlook. After this I can see both windows (my application and outlook) on my screen. I wait for any time and nothing happens. But if I put focus on my application or another or even press "hide all windows" in "Quick Launch panel" then message box shows immediately.

    For me it seems that messages from timer for some reason don't go to the windows que immediately and stuck somewhere or my application doesn't receive them for some reason.

    I can download somewhere my simple application because it looks like I cannot attach it to my reply.


    Tuesday, May 29, 2012 7:45 AM
  • is you machine a virtual one? or laptop?
    Tuesday, May 29, 2012 8:06 AM
  • No, my computer is desktop.

    Also I have tried my appliecation on several more machines and the program's behaviour is the same.

    Tuesday, May 29, 2012 8:48 AM
  • paste here whole code for your app (at least compilable detection logic) and i will try it out on my win7 machine
    Tuesday, May 29, 2012 8:51 AM
  • I checked simple timer application with simple counter and it works. With Outlook it still doesn't.

    Also if I see during debugging in "Output" window I see "A first chance exception of type 'System.Runtime.InteropServices.COMException' occurred in mscorlib.dll" each time I call Marshal.GetActiveObject("Outlook.Application") while Outlook is not opened.

    Here is my code. Form1.cs

    using System;
    using System.ComponentModel;
    using System.Timers;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using Microsoft.Office.Interop.Outlook;
    
    namespace testOutlook
    {
        public partial class Form1 : Form
        {
            private static System.Timers.Timer timer1;
            public Form1()
            {
                InitializeComponent();
                timer1 = new System.Timers.Timer(1000);
                //parameter set the timer1.Interval property to 1000
                timer1.Elapsed += new ElapsedEventHandler(OnTimedEvent);
                timer1.Start();
            }
    
            private void OnTimedEvent(object sender, EventArgs e)
            {
                bool aErr = false;
                Object obj = null;
                try
                {
                    obj = Marshal.GetActiveObject("Outlook.Application");
                }
                catch (System.Exception ex)
                {
                    aErr = true;
                }
                if (false == aErr)
                {
                    timer1.Stop();
                    MessageBox.Show("Success ", "Success");
                }
                else
                    return;
    
            }
        }
    }

    if it can help Form1.Designer.cs

    namespace testOutlook
    {
        partial class Form1
        {
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.IContainer components = null;
    
            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region Windows Form Designer generated code
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                this.SuspendLayout();
                // 
                // Form1
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(292, 266);
                this.Name = "Form1";
                this.Text = "Form1";
                this.ResumeLayout(false);
    
            }
            #endregion
        }
    }
    

    Thank you in advance,

      Michael.

    Tuesday, May 29, 2012 9:04 AM
  • There is nothing special, but...

    Also files Program.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    
    namespace testOutlook
    {
        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());
            }
        }
    }

    and AssemblyInfo.cs

    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    
    // General Information about an assembly is controlled through the following 
    // set of attributes. Change these attribute values to modify the information
    // associated with an assembly.
    [assembly: AssemblyTitle("testOutlook")]
    [assembly: AssemblyDescription("")]
    [assembly: AssemblyConfiguration("")]
    [assembly: AssemblyCompany("")]
    [assembly: AssemblyProduct("testOutlook")]
    [assembly: AssemblyCopyright("Copyright © 2012")]
    [assembly: AssemblyTrademark("")]
    [assembly: AssemblyCulture("")]
    
    // Setting ComVisible to false makes the types in this assembly not visible 
    // to COM components.  If you need to access a type in this assembly from 
    // COM, set the ComVisible attribute to true on that type.
    [assembly: ComVisible(true)]
    
    // The following GUID is for the ID of the typelib if this project is exposed to COM
    [assembly: Guid("2cbeb1a1-fdd1-4ac0-9c9a-61b37bf5b05e")]
    
    // Version information for an assembly consists of the following four values:
    //
    //      Major Version
    //      Minor Version 
    //      Build Number
    //      Revision
    //
    // You can specify all the values or you can default the Build and Revision Numbers 
    // by using the '*' as shown below:
    // [assembly: AssemblyVersion("1.0.*")]
    [assembly: AssemblyVersion("1.0.0.0")]
    [assembly: AssemblyFileVersion("1.0.0.0")]



    • Edited by Mikaell_A Tuesday, May 29, 2012 9:09 AM
    Tuesday, May 29, 2012 9:09 AM
  • Sorry, known issue

    http://support.microsoft.com/?scid=kb%3Ben-us%3B238610&x=10&y=11

    try to call activate on your program (so outlook looses focus) in your timer event - of course it will drive users insane :-)

    Tuesday, May 29, 2012 9:41 AM
  • I don't know how to thank you enough!

    That is great!

    Finally I have found a little bit better solution. I go through all processes (because in the list of processes Outlook will appear anyway) and if there is such process I call activate for some little window, which I close immediately, so GetActiveObject can work correctly.

    Tuesday, May 29, 2012 10:36 AM
  • great that you shared this trick with us, maybe it will help others :-)
    Tuesday, May 29, 2012 10:39 AM
  • When you loop through the running processes, make sure to check the process owner - outlook.exe can run for multiple users (e.g. Citrix) at the same time.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.3 is now available!

    Tuesday, May 29, 2012 3:25 PM