CustomTaskPanes and Invoking NewMailMessage from outside Outlook

1k views Asked by At

I have a ribbon button that appears on tabNewMailMessage in Outlook's compose email form, this button toggles the visibility of a CustomTaskPane stuck to the side of the form.

In normal practice, everything works perfectly. But when the Compose Email form is invoked via 'Attach to email' or 'Save & Send' from other applications like MS Word or Adobe Reader, the button appears but no longer does anything.

I learned from MSDN that the NewInspector event apparently does not fire in the case of external invocation.

I have not been able to find any workarounds for this case, does anybody here know? :(

EDIT : Additionally, I have a Global class (not the hidden GlobalS class that Visual Studio creates) that contains some variables I use across the entire program. The Addin will not load anything contained in there at all either. It's hard to tell what actually does get loaded, if anyone has more information, holler back please!

EDIT Again : Tested putting string in ThisAddIn and printing it through a messageBox in toggleButton, didn't work. If anyone is confused, the ribbon button will not load if the click-event is impossible to execute, so it seems that externally invoked Compose forms skip all code in ThisAddIn and any class that isn't the ribbon itself.

I really need help figuring this out! :(

EDIT Yet Again : Here is what I've garnered so far, ThisAddIn startup events will not fire, no properties in external classes may be read from, but external methods like say ThisAddIn.SayHelloWorld() do work.

EDIT again! :

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

        //MessageBox.Show(,"TEST");
        try
        {               
            inspectors = Globals.ThisAddIn.Application.Inspectors;
            inspectors.NewInspector += new InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);

            foreach (Inspector insp in inspectors)
            {
                //insp.
                Inspectors_NewInspector(insp);
            }
        }
        catch (System.Exception ex)
        {
            List<string> lalala = new List<string>();
            lalala.Add(ex.GetType().ToString());
            lalala.Add(ex.Message);
            lalala.Add(ex.StackTrace);
            File.WriteAllLines(@"C:\outdebug",lalala.ToArray());
        }
    }

Again! :

void Inspectors_NewInspector(Inspector Inspect)
    {
        try
        {
            if (Inspect.CurrentItem is MailItem)
            {
                Global.mail = Inspect.CurrentItem;
                Global.inspectorWrappersValue.Add(Inspect, new InspectorWrapper(Inspect, Global.mail));
                //inspectorw
            }
        }
        catch (System.Exception ex)
        {
            List<string> lalala = new List<string>();
            lalala.Add(ex.GetType().ToString());
            lalala.Add(ex.Message);
            lalala.Add(ex.StackTrace);
            lalala.Add(Global.SiteConnectionManager.ToString());
            File.WriteAllText(@"C:\Users\cat\Desktop\outdebug.txt", string.Join("\n", lalala), Encoding.UTF8);
        }
    }
1

There are 1 answers

24
Jean Libera On BEST ANSWER

It is a good idea to use try/catch handlers around all your code in ThisAddIn.Startup, because Outlook is aggressive about eating all exceptions, so if there is a problem you will never know it.

However, I think what is really causing you a problem is an Outlook issue discussed at http://social.msdn.microsoft.com/Forums/en/vsto/thread/60c75274-e15a-4696-afa6-79de8fbd707d. The solution is to create a timer and check if there are existing inspectors when it fires. What I have below should help out a lot, but it's not a complete solution because it doesn't handle the case where NewInspector fires and the timer also indicates an inspector. So you will have to add some logic to make sure you don't add 2 task panes for an inspector.

public partial class ThisAddIn
{
    private DispatchTimer _newInspectorStartupTimer;

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        try
        {
            // check for existing explorers and inspectors and
            // set up event handlers for new ones

            // here is how you set up the inspector event handler:
            ThisAddIn.Application.Inspectors.NewInspector += new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);

            // create a timer.  When the timer fires, check if any
            // Inspector windows currently exist, and add task panes
            // for them if needed.
            _newInspectorStartupTimer = new DispatcherTimer();
            _newInspectorStartupTimer.Interval = TimeSpan.FromSeconds(2.0);
            _newInspectorStartupTimer.Tick += new EventHandler(NewInspectorStartupTimer_Tick);
            _newInspectorStartupTimer.Start();
        }
        catch (System.Exception ex)
        {
            // log the exception type, message, and stack trace here
        }
    }

    private void NewInspectorStartupTimer_Tick(object sender, EventArgs e)
    {
        int inspectorCount = _inspectors.Count;
        if (inspectorCount > 0)
        {
            for (int i = 1; i <= _inspectors.Count; ++i)
            {
                Inspector inspector = _inspectors[i];
                Inspectors_NewInspector(inspector);
            }
        }
    }

    // Inspectors_NewInspector also has a try/catch.  Note that
    // Inspectors_NewInspector will be called multiple times
    // for each inspector, due to the timer.
    private void Inspectors_NewInspector(Inspector inspector)
    {
        try
        {
            // you need to check whether you have already created a
            // task pane for this inspector.  If not, create your
            // task pane here.
        }
        catch (System.Exception ex)
        {
            // log the exception type, message, and stack trace here
        }
    }