Help: Excel 2007 crashes after unloading Add-In

M

Mel Green

Hi there,

I've seem to run into an interesting problem with an Add-In that I
originally wrote for Excel 2003 and below, and then tried to run with Excel
2007. The Add-In is written in ATL C++ and uses the IDispatchImpl and
IDispEventSimpleImpl interfaces to communicate events with Excel.

While the Add-In works perfectly for Excel 2000-2003, excel will crash with
an error AFTER Excel unloads the GUI and all the Add-Ins. During the time
that Excel is open my Add-In works great. I've tried to debug the code to
find out what is happening, but there are no exceptions thrown anywhere in my
code. I can go all the way to the point where Excel calls my
OnDisconnection() and subsequently OnBeginShutdown() functions at which point
I return S_OK. It is then, if I walk through some of the assembly code in
Excel I get to a point where a NULL reference exception is encountered.

The only thing my Add-In does is create a new Command Bar and adds a button
to it. By the process of commenting out all of the code inside my functions
and then slowly enabling some I've found that the code that is somehow
causing this problem is the code that creates my Command Bar.

The code I use to create the command bar is fired in the OnStartupComplete()
event of the IDispatch interface and does this:

<---------------------------------------------------------------------------

//Members used to insert the button(s)
CCommandBars oCommandBars;

//Setup the application
CApplication spApp(m_pApplication);

//Get the collection of command bars
oCommandBars = spApp.get_CommandBars();

//Now add a new toolband to which we'll add a button
CComVariant vName("MyBar");
CComVariant vEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR);
CComVariant vVisible(VARIANT_TRUE);
CComQIPtr<Office::CommandBar> oMyBar;

//Loop through the collection of command bars and see if our bar
//already exists
BSTR tmp;
for(int i = 1; i < oCommandBars.get_Count(); i++)
{
CComVariant vIndex(i);
oEFileBar = oCommandBars.get_Item(vIndex);
oEFileBar->get_Name(&tmp);
if(strcmp(ConvertBSTRToString(tmp), "MyBar"))
{
oMyBar.Detach();
}
else
break;
}
//free the string
::SysFreeString(tmp);


//If we didn't find the bar already there, create it
if(!oMyBar)
{

//position it below all toolbands
//MsoBarPosition::msoBarTop = 1
CComVariant vPos(1);
CComVariant vTemp(VARIANT_TRUE); //menu is temporary


//Add a new toolband through Add method
//vMenuTemp holds an unspecified parameter
oMyBar = oCommandBars.Add( vName, vPos, vEmpty, vTemp );

}

------------------------------------------------------------------------------->

Instead of using the regular ATL convention of
ComQIPtr<Office::CommandBars>, I used a MFC class creator for COM interfaces
to create these wrapper classes (CCommandBars and CApplication) to make the
code simpler. This has worked fine for me.
 
G

Georg-Hendrik

Hi Mel,

It seems that we have the same issue: I'm developing a Outlook plug-in with
ATL C++ which works fine, right until shutdown. It fails with an 'Illegal
Instruction' somewhere in MS library code.
I have also isolated the problem in an application that does nothing but add
a menuitem to the active menubar.
A difference is that in my case, I don't receive a BeginShutdown nor
Disconnect - it just fails.

Have a look at my previous post here, if you will:
http://www.microsoft.com/communitie...dins&mid=f3a8d022-9a55-420a-907a-ed162fe90d29

I think there is a fair chance that whatever the solution is, it will solve
both our problems.

Georg-Hendrik
 
M

Mel Green

Thanks Georg,

It's nice to know that this isn't a completely unique problem. Although,
like yourself, I fail to see the error in either of our two programs. If
you'd like though, I too have recently developed a COM Add-In for Outlook
using C++\ATL which uses code much like yours. If you'd like I could send you
my source and you can either use some of it or see where it differs.

I really haven't made any more headway on this and that's a really
frustrating thing for a programmer. I have found out a couple more
interesting "flaky" behaviors about this bug. When I run the program from
inside Visual Studio 2003 (which is the IDE I'm using), and I put a
breakpoint anywhere in my active code (or even anywhere in the assembly of
Excel) this exception never happens. But if I just start the debugging
without any breakpoints, or run Excel manually outside VS, I will get this
bug.

Another thing is when I restart the computer (any computer running the
Add-In, not just mine) the first time I run Excel this exception won't occur
when it closes. But every time after that it will always crash on this
exception when it closes.

I've also done some research online and found a rather dated incident where
a common "Send to Bluetooth" Excel Add-In caused the exact same behavior with
Excel 2007. I think the add-in might have been developed by Broadcom, but I'm
not sure. So needless to say I can't find out what they did to fix it.

If there's anyone out there that's seen any of this behavior before, related
or not, I'd really love to hear about it. I could use all the help I can
get... short of scratching the whole thing and writing a completely separate
Add-In just for Excel 2007.

Thanks again Georg, I'll be sure to reply to your post as well if I ever
find out anything.

~Mel
 
A

Andrei Smolin [Add-in Express]

Mel,

Looks like you don't release some COM reference(s). However, the code you
posted isn't enough to understand the real cause. Can you send me the
project (or any test project with the same behavior) for testing?

Regards from Belarus,

Andrei Smolin
Add-in Express Team Leader
www.add-in-express.com
 
M

Mel Green

Thanks Andrei,

I've emailed the project to the address you have listed in your profile. Any
insight would be great!

Please let me know if there's any additional information you could use. It
would be the greatest thing to be able to get this to work!

Thanks,

Mel
 
A

Andrei Smolin [Add-in Express]

Mel,

In the DotDispatchDriver.cpp file, you need to change the constructor of the
CDotDispatchDriver class as shown below:

CDotDispatchDriver::CDotDispatchDriver(LPDISPATCH lpDispatch, BOOL
bAutoRelease)
{
m_lpDispatch = lpDispatch;
if (m_lpDispatch != NULL && bAutoRelease == TRUE)
m_lpDispatch->AddRef();
m_bAutoRelease = bAutoRelease;
}

Regards from Belarus,

Andrei Smolin
Add-in Express Team Leader
www.add-in-express.com
 
M

Mel Green

Thank you very much Andrei, that fixed it!!!

I don't know what I would have done without you.

Sincerely,

Mel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top