Exception when updating image on ribbon button

Add-in Express™ Support Service
That's what is more important than anything else

Exception when updating image on ribbon button
 
Bargholz Thomas




Posts: 236
Joined: 2006-12-18
Hi,

we have an add-in for Outlook which on some users PC's (not all, only a few) causes an exception, when a buttons image is updated in certain situations.

This is the background:

We have a static class with a timer, which when triggered, runs a worker thread that calls a service to get some information. In the worker threads RunWorkerComplete event, this static class then raises an event, to tell the class caller, that the UI can now be updated with the latest data.


// event
public delegate void CheckedoutCountEventHandler(object sender, int count);
public static event CheckedoutCountEventHandler CheckedoutCount;
private static void RaiseCheckedoutCount(int count)
{
    if (CheckedoutCount != null)
        CheckedoutCount(null, count);
}

// when timer is elapsed
private static void m_executeTimer_Elapsed(object sender, ElapsedEventArgs e)
{
    m_executeTimer.Stop();
    m_workerThread = new BackgroundWorker();
    m_workerThread.DoWork += m_workerThread_DoWork;
    m_workerThread.RunWorkerCompleted += m_workerThread_RunWorkerCompleted;
    m_workerThread.RunWorkerAsync();
}

// backrgoud thread stuff
private static void m_workerThread_DoWork(object sender, DoWorkEventArgs e)
{
    // call service here and update class variables with return values
}

private static void m_workerThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{            
    RaiseCheckedoutCount(m_checkoutCount);
    m_executeTimer.Start();
}



This event is monitored from my AddIn module, which then updates the UI depending on the data being returned from the event:


// event is attached in AddinStartupComplete:
NotificationEvents.CheckedoutCount += NotificationEvents_CheckedoutCount;

// when event is triggered, update the UI
private void NotificationEvents_CheckedoutCount(object sender, int count)
{
    if (count > 0)
    {
        adxRibbonButtonStatusCheckedout.Image = 1;
    }
    else
    {
        adxRibbonButtonStatusCheckedout.Image = 2;
    }
}


On a few of the users PC's, this causes and unhandled exception with this stacktrace:

System.Runtime.InteropServices.InvalidComObjectException
at System.StubHelpers.StubHelpers.GetCOMIPFromRCW(System.Object, IntPtr, IntPtr ByRef, Boolean ByRef)
at AddinExpress.MSO.IRibbonUI.InvalidateControl(System.String)
at AddinExpress.MSO.ADXRibbonCustomControl.Invalidate()
at AddinExpress.MSO.ADXRibbonCustomControl.AddinExpress.MSO.IADXRibbonComponent.set_Image(Int32)
at AddinExpress.MSO.ADXRibbonButton.set_Image(Int32)
at AddIn.AddinModule.NotificationEvents_CheckedoutCount(System.Object, Int32)
at NotificationEvents.RaiseCheckedoutCount(Int32)
at NotificationEvents.m_workerThread_RunWorkerCompleted(System.Object, System.ComponentModel.RunWorkerCompletedEventArgs)


We are using Add-In-Express version 8.3.4393.0, with support for Outlook 2010, 2013 and 2016.
Issue is most commonly seen on Outlook 2016.

Regards
Thomas
Posted 20 Jun, 2017 03:08:01 Top
Andrei Smolin


Add-in Express team


Posts: 14137
Joined: 2006-05-11
Hello Thomas,

since the buttons are created on the main thread, you should raise the CheckedoutCount on the main thread as well. To do so, use the fact that the ADXAddinModule.OnSendMessage event always occurs on the main thread. That is, instead of calling RaiseCheckedoutCount() in m_workerThread_RunWorkerCompleted, you call ADXAddinModule.SendMessage(%a unique integer > 1024%). The next phase is the OnSendMessage event: when it occurs and e.Message is equal to %a unique integer > 1024%, you call RaiseCheckedoutCount(). Store the data required for this method in a class-level variable.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 20 Jun, 2017 03:27:49 Top