Search code examples
c#outlook-addinribboninvalidation

Ribbon Invalidate makes my outlook add-in crash


I have a pretty large outlook add-in with following ribbon.xml:

<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="Ribbon_Load">
  <ribbon>
    <tabs>
      <tab idMso="TabMail">
    <group id="groupViewHome" label="View tasks">
      <toggleButton id="buttonToggleHistoryHome" getLabel="getLabelToggleHistory" imageMso="ControlToggleButton" onAction="toggleHistory_Click" size="large" getPressed="getEnabledToggleHistory" />
    </group>
      </tab>
      <tab idMso="TabAddIns" label="DCP">
    <group id="groupCreateTask" label="Create a task">
      <button id="buttonNewTask" label="New Task" imageMso="QueryAppend" onAction="buttonNewTask_Click" size="large" getEnabled="getMailSelected" />
    </group>
    <group id="groupEdit" label="Edit a task">
      <button id="buttonAddSelection" label="Copy selection to task" imageMso="QueryUpdate" onAction="selectedText_Click" size="large" getEnabled="getMailAndIDSelected"/>
    </group>
    <group id="groupView" label="View tasks">
      <button id="buttonTaskHistory" imageMso="FileDocumentInspect" onAction="taskInfo_Click" getLabel="getButtonHistoryLabel" />
      <toggleButton id="buttonToggleHistory" getLabel="getLabelToggleHistory" imageMso="ControlToggleButton" onAction="toggleHistory_Click" getPressed="getEnabledToggleHistory" />
      <checkBox id="buttonTriggerMail" label="Toggle auto-history" onAction="Trigger_Click" getPressed="getInitialTriggerState"/>
    </group>
    <group id="groupAttach" label="Attachments">
      <button id="saveMail2" label="Add mail as .msg attachment" imageMso="AttachItem" onAction="saveMail_Click" getEnabled="getMailAndIDSelected"/>
      <button id="selectAttach" label="Select attachments to add" imageMso="AttachMenu" onAction="selectAttach_Click" getEnabled="getMailAndIDSelectedAndAttach"/>
    </group>
    <group id="groupLinks" label="Hyperlinks">
      <button id="addLinkToMail" label="Add task link to mail body" imageMso="HyperlinkInsert" onAction="addLink_Click" size="large" getEnabled="getMailAndIDSelected"/>
    </group>
      </tab>
    </tabs>
  </ribbon>
  <contextMenus>
    <contextMenu idMso="ContextMenuReadOnlyMailText">
      <menu id="dcp" label="DCP">
    <button id="selectedText" label="Copy selection to task" imageMso="CitationInsert" onAction="selectedText_Click"/>
    <button id="addTask" label="New task" imageMso="GoToNewRecord" onAction="buttonNewTask_Click" />
      </menu>
    </contextMenu>
    <contextMenu idMso="ContextMenuReadOnlyMailTable">
      <menu id="dcp3" label="DCP">
    <button id="selectedText2" label="Copy selection to task" imageMso="CitationInsert" onAction="selectedText_Click"/>
    <button id="addTask3" label="New task" imageMso="GoToNewRecord" onAction="buttonNewTask_Click" />
      </menu>
    </contextMenu>
    <contextMenu idMso="ContextMenuReadOnlyMailTableCell">
      <menu id="dcp4" label="DCP">
    <button id="selectedText3" label="Copy selection to task" imageMso="CitationInsert" onAction="selectedText_Click"/>
    <button id="addTask4" label="New task" imageMso="GoToNewRecord" onAction="buttonNewTask_Click" />
      </menu>
    </contextMenu>
    <contextMenu idMso="ContextMenuReadOnlyMailListTable">
      <menu id="dcp5" label="DCP">
    <button id="selectedText4" label="Copy selection to task" imageMso="CitationInsert" onAction="selectedText_Click"/>
    <button id="addTask5" label="New task" imageMso="GoToNewRecord" onAction="buttonNewTask_Click" />
      </menu>
    </contextMenu>
    <contextMenu idMso="ContextMenuReadOnlyMailPictureTable">
      <menu id="dcp6" label="DCP">
    <button id="selectedText5" label="Copy selection to task" imageMso="CitationInsert" onAction="selectedText_Click" />
    <button id="addTask6" label="New task" imageMso="GoToNewRecord" onAction="buttonNewTask_Click" />
      </menu>
    </contextMenu>
    <contextMenu idMso="ContextMenuReadOnlyMailTextTable">
      <menu id="dcp7" label="DCP">
    <button id="selectedText6" label="Copy selection to task" imageMso="CitationInsert" onAction="selectedText_Click"/>
    <button id="addTask7" label="New task" imageMso="GoToNewRecord" onAction="buttonNewTask_Click" />
      </menu>
    </contextMenu>
    <contextMenu idMso="ContextMenuReadOnlyMailTableWhole">
      <menu id="dcp8" label="DCP">
    <button id="selectedText7" label="Copy selection to task" imageMso="CitationInsert" onAction="selectedText_Click" />
    <button id="addTask8" label="New task" imageMso="GoToNewRecord" onAction="buttonNewTask_Click" />
      </menu>
    </contextMenu>
    <contextMenu idMso="ContextMenuReadOnlyMailList">
      <menu id="dcp9" label="DCP">
    <button id="selectedText8" label="Copy selection to task" imageMso="CitationInsert" onAction="selectedText_Click" />
    <button id="addTask9" label="New task" imageMso="GoToNewRecord" onAction="buttonNewTask_Click" />
      </menu>
    </contextMenu>
    <contextMenu idMso="ContextMenuReadOnlyMailHyperlink">
      <menu id="dcp10" label="DCP">
    <button id="selectedText9" label="Copy selection to task" imageMso="CitationInsert" onAction="selectedText_Click" />
    <button id="addTask10" label="New task" imageMso="GoToNewRecord" onAction="buttonNewTask_Click" />
      </menu>
    </contextMenu>
    <contextMenu idMso="ContextMenuMailItem">
      <menu id="dcp2" label="DCP">
    <button id="buttonTaskHistoryMail" label="View task history" imageMso="SourceControlShowHistory" onAction="taskInfo_Click" />
    <button id="addTask2" label="New task" imageMso="GoToNewRecord" onAction="buttonNewTask_Click" />
    <button id="saveMail" label="Add mail as .msg attachment" imageMso="AttachItem" onAction="saveMail_Click" />
      </menu>
    </contextMenu>
    <contextMenu idMso="ContextMenuAttachments">
    <button id="buttonAddAttachment" label="Add attachment to task" imageMso="AttachMenu" onAction="addAttachment_Click"/>
    </contextMenu>
  </contextMenus>
</customUI>

As you can see I have a couple of actions that require invalidation to enable, toggle... my buttons. My add-in starts up fine but crashes on some occasions. The following are some examples on which the add-in almost always crashes:

  • Opening a mail item in a new inspector window and closing it again
  • Multiple windows open, context menu with custom button in it is opened

The occasions in which it occurs make me pretty sure it has everything to do with the automatic invalidation on creation of a new context menu or ribbon, not when I call it myself. The error does not persist when I remove the getEnabled, getPressed... attributes. I can't figure out a way to surpress the error instead of crashing or how to fix it. So if anybody can help or can give me more info on this it would be much appreciated. If you need any more code (like the getEnabled, getPressed... methods), let me know.

My invalidate methods. Note that most just return a boolean. These booleans are kept as a private variable inside the ribbon.cs class

public bool getEnabledToggleHistory(IRibbonControl control)
{
   return toggleHistoryPanelState;
}

public bool getMailSelected(IRibbonControl control)
{
    try
    {
        MailItem mailItem = getMail();
        if (mailItem != null)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    catch (System.Exception ex)
    {
        return false;
    }
}

public bool getMailAndIDSelected(IRibbonControl control)
{
    return mailAndIDSelected;
}

public bool getMailAndIDSelectedAndAttach(IRibbonControl control)
{
    if (hasAttachments && mailAndIDSelected)
    {
        return true;
    }
    return false;
}

If I debug in a new Visual Studio instance I get the following:

Unhandled exception at 0x70B5B2A7 (MSO.DLL) in OUTLOOK.EXE: 0xC0000005: Access violation reading location 0x00000000.

If I debug the code from my solution I can never catch the error, nor does it say it has an unhandled one. It just crashes.


Solution

  • (posting sort of an 'answer' based on our discussion in the comments)

    If you can't catch it or log (don't just catch exceptions, put something into dump - you can dump into temp user folder)...

    My best suggestion, the good old divide and conquer - remove everything (you already said only 'flags' are causing it), just leave one button with one thing in it - 'return' all methods until you get one causing all the problems - something like that.

    (OL XML system for ribbons etc. is very error prone - so you need to check everything (be meticulous) - and OL errors aren't very descriptive, most of the time just crashes. Btw what happens if you just remove the whole context-menu?)