none
How to ensure, that an addin has been initialized completely RRS feed

  • Question

  • Hi,

    Me and my colleagues found a situation with a modal inspector (file -> send to -> email recipient) where our add-in sometimes doesn't load completely. A method called by the ThisAddIn_Startup event handler invokes another process and uses _myProcess.WaitForExit(int timeout). Now there happens something i've never expected: The message pipe of the modal inspector gets active while waiting for this process and sometimes eats the message, which would cause the WaitForExit method to return to the normal execution flow. Result is: The inspector works, but the add-in gets stuck in the initialization. Really freaky is that our add-in reacts to ribbon clicks in the same thread as it hangs in the other method.

    So my question: Is there a way to ensure, that Outlook waits with displaying the window until my add-in gets initialized completely? Or do someone of you have another idea how to do that?

    Thanks, Daniel

    Tuesday, August 19, 2014 2:04 PM

Answers

  • Hello Daniel,

    No, there is no way. However, Outlook loads add-ins using the single thread. So, the add-in should be initialized before the inspector/explorer window is displayed.

    You need to handle the NewInspector or Activate events (see the Inspector class) also. Check out whether any Explorer window exists at this time. If not, Outlook is started using the SendTo command.

    The What's new for Outlook 2013 developers article in MSDN states the following:

    Extending the add-in resiliency pillar of Outlook 2010, Outlook 2013 monitors add-in performance metrics such as add-in startup, shutdown, folder switch, item open, and invoke frequency. Outlook records the elapsed time in milliseconds for each performance monitoring metric.

    For example, the startup metric measures the time required by each connected add-in during Outlook startup. Outlook then computes the median startup time over 5 successive iterations. If the median startup time exceeds 1000 milliseconds (1 second), then Outlook disables the add-in and displays a notification to the user that an add-in has been disabled. The user has the option of always enabling the add-in, in which case Outlook will not disable the add-in even if the add-in exceeds the 1000 millisecond performance threshold

    You shouldn't overload the startup time to prevent your add-in from disabling.


    Tuesday, August 19, 2014 2:15 PM
  • When Outlook is called from Simple MAPI (send to) no NewInspector() event is ever fired. The Inspector is added to the Inspectors collection, but there is no notification of that whether or not Outlook and an addin were running previously or not.

    To know if a Simple MAPI Inspector was added to Inspectors you would need to periodically sweep the Inspectors collection and check for Inspectors that weren't handled by NewInspector(). I often use a Windows.Forms.Timer for that as it would run in the main addin thread. That's important as the Outlook object model should never be called from any background threads.

    If the initialization process doesn't involve calling the Outlook object model it could be started on a background thread. If the process needs UI for some reason it would need to invoke the UI on the foreground thread or synchronize thread contexts to show UI on the foreground thread.


    Ken Slovak MVP - Outlook

    Wednesday, August 20, 2014 1:36 PM
    Moderator
  • You cannot control Outlook's message pipe or how it pumps messages. What is waiting is *your* code, not the underlying Outlook code. When you wait on a return you aren't hanging or waiting Outlook, it's your addin code that's waiting.

    I suggest starting a background thread for your process.


    Ken Slovak MVP - Outlook

    Wednesday, August 20, 2014 2:05 PM
    Moderator
  • Even starting a process from another thread will not help to finish it earlier. I'd reconsider the whole architecture for using async operations.

    @Ken, the Activate event is fired.


    Wednesday, August 20, 2014 2:10 PM
  • No, but it would allow addin startup to finish.

    I do agree though about thinking about re-architecting the solution to get that process out of startup, and possibly thinking about async calls.


    Ken Slovak MVP - Outlook

    Wednesday, August 20, 2014 2:14 PM
    Moderator

All replies

  • Hello Daniel,

    No, there is no way. However, Outlook loads add-ins using the single thread. So, the add-in should be initialized before the inspector/explorer window is displayed.

    You need to handle the NewInspector or Activate events (see the Inspector class) also. Check out whether any Explorer window exists at this time. If not, Outlook is started using the SendTo command.

    The What's new for Outlook 2013 developers article in MSDN states the following:

    Extending the add-in resiliency pillar of Outlook 2010, Outlook 2013 monitors add-in performance metrics such as add-in startup, shutdown, folder switch, item open, and invoke frequency. Outlook records the elapsed time in milliseconds for each performance monitoring metric.

    For example, the startup metric measures the time required by each connected add-in during Outlook startup. Outlook then computes the median startup time over 5 successive iterations. If the median startup time exceeds 1000 milliseconds (1 second), then Outlook disables the add-in and displays a notification to the user that an add-in has been disabled. The user has the option of always enabling the add-in, in which case Outlook will not disable the add-in even if the add-in exceeds the 1000 millisecond performance threshold

    You shouldn't overload the startup time to prevent your add-in from disabling.


    Tuesday, August 19, 2014 2:15 PM
  • Thank you Eugene.

    I already knew this with the time measurement of Outlook 2013 but - bad luck - Add-In-Express (Regions) needs more that a second to load up. Therefore my add-in needs in total about 1.3 seconds to load, sometimes up to 2 seconds (on my developer system). But that doesn't seem to be the problem.

    The real problem is that my add-in gets stuck in the _myProcess.WaitForExit method for much longer then the given timeout. Therefore the rest of my initialization doesn't get executed (as the adx-regions initialization and displaying). I do not use this method in another thread, i only use 2 threads to read the standard error and output streams of the process. But they worked for years and still working as usual when working with non-modal inspectors as it is usual with a normal opened outlook.

    Wednesday, August 20, 2014 8:09 AM
  • Most probably some of your code is not run when Outlook is started via the mailto command. Try to add trace statements and see what's wrong with the code.

    Also I'd suggest initializing and showing your panes after Outlook is started and initialized. For example, you may handle the Startupevent of the Application class which is fired when Microsoft Outlook is starting, but after all add-in programs have been loaded. So, you can start displaying your forms and initialize the data. Thus, you will decrease the startup time as much as possible.

    Wednesday, August 20, 2014 10:41 AM
  • Thanks Eugene.

    Our Add-In already uses the Startup-Event of the Application object (as usual with VSTO). Also i can guarantee that the issue has nothing to do with the startup times. We also have this issue on Outlook 2010. Also i can see in the logfiles, that the initialization sometimes works just fine, sometimes it stops here and then at another point, but everytime in the same method, where the process will be executed. Also when attaching the debugger in this situation and pausing the program, the execution pointer is inside the WaitForExit method of my process.

    Wednesday, August 20, 2014 10:51 AM
  • It seems the cause of the issue is located in your code (which is run in another threads/processes?).

    Try to add trace statements and see what's wrong with the code.

    Wednesday, August 20, 2014 11:11 AM
  • When Outlook is called from Simple MAPI (send to) no NewInspector() event is ever fired. The Inspector is added to the Inspectors collection, but there is no notification of that whether or not Outlook and an addin were running previously or not.

    To know if a Simple MAPI Inspector was added to Inspectors you would need to periodically sweep the Inspectors collection and check for Inspectors that weren't handled by NewInspector(). I often use a Windows.Forms.Timer for that as it would run in the main addin thread. That's important as the Outlook object model should never be called from any background threads.

    If the initialization process doesn't involve calling the Outlook object model it could be started on a background thread. If the process needs UI for some reason it would need to invoke the UI on the foreground thread or synchronize thread contexts to show UI on the foreground thread.


    Ken Slovak MVP - Outlook

    Wednesday, August 20, 2014 1:36 PM
    Moderator
  • Many thanks Ken.

    First of all i would again try to explain, that i do not use a thread to separate the initialization in 2 parts with background working. All is done in the main thread. I only use threads while the process is dumping characters to its streams to fetch them.

    My big problem is (still), that my add-in stucks - in the main thread - in the Process.WaitForExit function while outlook is working fine and handling all of its mouse and keyboard events. How can that be? How in the *** world can outlook open up its message pipe while i wait for a function to return?

    I want outlook to stop that and first let me initialize completely before starting its message pipe.

    @Eugene: Even if i do not use Trace arguments, i write a logfile and that tells me the same as the debugger. My code stands completely still, while outlook works more or less fine.

    Wednesday, August 20, 2014 1:44 PM
  • You cannot control Outlook's message pipe or how it pumps messages. What is waiting is *your* code, not the underlying Outlook code. When you wait on a return you aren't hanging or waiting Outlook, it's your addin code that's waiting.

    I suggest starting a background thread for your process.


    Ken Slovak MVP - Outlook

    Wednesday, August 20, 2014 2:05 PM
    Moderator
  • Even starting a process from another thread will not help to finish it earlier. I'd reconsider the whole architecture for using async operations.

    @Ken, the Activate event is fired.


    Wednesday, August 20, 2014 2:10 PM
  • No, but it would allow addin startup to finish.

    I do agree though about thinking about re-architecting the solution to get that process out of startup, and possibly thinking about async calls.


    Ken Slovak MVP - Outlook

    Wednesday, August 20, 2014 2:14 PM
    Moderator
  • Many thanks to you two. I will talk about that with my colleagues and evaluate the architectural changes.

    // Still upset because Outlook eats my messages :(

    Wednesday, August 20, 2014 2:17 PM