Strange IsActivated problem in Excel Addin in Session 0

Hi Wyatt, we have a really strange and serious problem in our product.

We develop an Excel Addin and during the initialization of it we are checking if the product is Active. Unluckily this addin sometimes is being scheduled from Windows Session 0 (because another of our product uses Excel in Session 0) and here problems begins.

If just one Excel is opened in session 0 there is no problem. But if another Excel is opened while the first one was still open the call to IsActivated fire a kind of "process all pending messages in the process" that block the loading of the addin and then allow Excel to complete the rest of its work (that being an Automation work is carried trough WM messages). This is done until the unload of Excel and just after it the code that was previously executing into the initialization of the addin is completed, driving into a series of Access violation because all the objects that should be created at that point doesn't exists anymore (because destroyed from the shutdown of excel)

The fact that IsActivated fires this kind of "process all pending messages in the process" procedure is the following call stack

dxHooks.dxSystemGetMessageHook(0,0,1232208):75b17a1a ; C:\Windows\system32\USER32.dll:75b1e1a9 ; C:\Windows\system32\USER32.dll:75b2248f USER32.PtInRect + 0xfd:77126fce ntdll.KiUserCallbackDispatcher + 0x2e:75b264a1 ; C:\Windows\system32\USER32.dll:759ccf70 ; C:\Windows\system32\ole32.dll:759cd1ab ; C:\Windows\system32\ole32.dll:759cd093 ; C:\Windows\system32\ole32.dll:759cd048 ; C:\Windows\system32\ole32.dll:759d2d31 ; C:\Windows\system32\ole32.dll:75aed2f6 ; C:\Windows\system32\ole32.dll:75aed098 ; C:\Windows\system32\ole32.dll:75aecef0 ; C:\Windows\system32\ole32.dll:759d2cba ; C:\Windows\system32\ole32.dll:759e9aa1 ; C:\Windows\system32\ole32.dll:759e9b24 ; C:\Windows\system32\ole32.dll:75aece06 ; C:\Windows\system32\ole32.dll:77284926 ; C:\Windows\system32\RPCRT4.dll:75aec8e2 ; C:\Windows\system32\ole32.dll:759e98ad ; C:\Windows\system32\ole32.dll:6ec7e6dd ; C:\Windows\system32\wbem\fastprox.dll:5ea2c561 ; C:\Users\etomm\AppData\Local\Temp\C367EDCC1F69411388ACA31D3A556182:5ea2d65d ; C:\Users\etomm\AppData\Local\Temp\C367EDCC1F69411388ACA31D3A556182:5ea25310 ; C:\Users\etomm\AppData\Local\Temp\C367EDCC1F69411388ACA31D3A556182:5ea30bf8 C367EDCC1F69411388ACA31D3A556182.IsActivated + 0x84TurboActivatUtil.TurboActivateEx.IsActivated

TurboActivatUtil.TurboActivateEx.IsActivated is the Delphi function that call the TurboActivate.dll IsActivated

C:\Users\etomm\AppData\Local\Temp\C367EDCC1F69411388ACA31D3A556182 is the TurboActivate.dll

I'm having a bit of trouble understanding what you're doing and even what is going wrong.

Firstly, where in your addin are you calling IsActivated()? Are you calling it in the DLL_MAIN() function of your add-in?

The fact that IsActivated fires this kind of "process all pending messages in the process" procedure is the following call stack

What do you mean by "process all pending messages in the process"?

IsActivated is called in a function (called by Excel) to notify the "com" object to initialize. Let's call it Initialize.

With "process all pending messages in the process" I mean that suddendly, IsActivated is going to run something that is like Application.ProcessMessages in Delphi. A cycle that take every single WM message in the queue of the thread to elaborate it.

Because all the COM automation is done trough WM messages this "cycle" is letting Excel to "go on" with the automation and because at the end it would be closed, it unload also the Addin. The unload is going to destroy all objects.

When the automation is ending, before excel process is being closed, the elaboration start back from where it left in the Initialize (let's say just after the IsActivated call). This is obviously undesired because at that point almost all objects has been destroyed and memory of the dll freed. And this causes AV all over the execution.

As you can see from the following peace of call stack, you are calling something that then is going to execute some code in fastprox.dll.

:6ec7e6dd ; C:\Windows\system32\wbem\fastprox.dll:5ea2c561 ; C:\Users\etomm\AppData\Local\Temp\C367EDCC1F69411388ACA31D3A556182:5ea2d65d ; C:\Users\etomm\AppData\Local\Temp\C367EDCC1F69411388ACA31D3A556182:5ea25310 ; C:\Users\etomm\AppData\Local\Temp\C367EDCC1F69411388ACA31D3A556182:5ea30bf8 C367EDCC1F69411388ACA31D3A556182.IsActivated + 0x84

Just to help you, I noticed this strange behavior just when two excel process are fired at the same time, if just one Excel process is opened the Initialize function never enter in that strange cycle.

IsActivated is called in a function (called by Excel) to notify the "com" object to initialize. Let's call it Initialize.

Why not wait for Excel to intialize COM, and then call IsActivated()? Because as it is now, if the running process (in this case Excel) hasn't already initialized COM, then TurboActivate will initialize COM for the process. If TurboActivate doesn't initialize COM in the way Excel expects then you might run into some problems.

Thus, let Excel initialize COM first, then call the TurboActivate functions.

IsActivated is called in a function (called by Excel) to notify the "com" object to initialize. Let's call it Initialize.

Why not wait for Excel to intialize COM, and then call IsActivated()? Because as it is now, if the running process (in this case Excel) hasn't already initialized COM, then TurboActivate will initialize COM for the process. If TurboActivate doesn't initialize COM in the way Excel expects then you might run into some problems.

Thus, let Excel initialize COM first, then call the TurboActivate functions.

But Excel initialized COM for sure because it is running all plugins usually in separated threads. And if there is only one Excel usually TurboActivate is not giving any kind of problem.

Apart this we are needing to know if TurboActivate is activated to set to false or true the ribbon or the controlbar buttons.

The strange thing is that I'm able to reproduce this bug JUST if I'm forcing two instances of Excel automated.

Do you have debug symbols for TurboActivate? Maybe I can try to reproduce the bug and give to you the call names.

The strange thing is that I'm able to reproduce this bug JUST if I'm forcing two instances of Excel automated.

Do you run into this problem when you run 2 normal instances of Excel?

Do you have debug symbols for TurboActivate?

No, but can you tell me exactly where in Excel you're calling IsActivated()?

The strange thing is that I'm able to reproduce this bug JUST if I'm forcing two instances of Excel automated.

Do you run into this problem when you run 2 normal instances of Excel?

Do you have debug symbols for TurboActivate?

No, but can you tell me exactly where in Excel you're calling IsActivated()?

I have not been able to reproduce the bug with a normal Excel instance. The bug happened to me just when Excel is a COM server automated in "Session 0" and just when there are at least two Excel instances opened at the same time (in fact during debugging, the first instance is completing its work and beginning to close, at that point the second is starting and crashing).

IsActivated() is called from Excel trough the interface method _IDTExtensibility2.OnStartupComplete. When it is called the execution is blocking and going on until _IDTExtensibility2.OnBeginShutdown and at that point freeing all objects. This is meaning that when the execution is returning to complete the OnStartupComplete everysingle object will be freed and every single usage of them will result in an AV.

Wyatt we are needing to debug this problem somehow. What do you suggest?

Wyatt we are needing to debug this problem somehow. What do you suggest?

It would be most helpful if you could create a simple stripped-down add-in that reproduces this behavior. Then we'll be able to debug this here on our computers.

A couple more questions:

  1. What version of Excel are you running? Do you have the latest service packs and patches installed?
  2. What version of TurboActivate are you using? If you're not using the latest version, can you upgrade and try again?
  3. Was the trace you posted in the first post a trace of the crash or just a trace up to the point of IsActivated() being called?

For the environment we can give you both the Addin and a copy of the other product and prepare an environment that you can debug if this is the case. Were can I publish all the instructions, you will need license codes and a special version of the Addin (right now the addin extract the dll from the resources) and the crash require a way to hook excel or it will close and crash before you will be able to hook the process in debug mode. If you like this solution I will send you a mail directly from our internal case.

For the other questions1) I don't think it is Excel version dependant. It crashed with both 2003 and 2010. Our addin require at least excel 2003. They are always patched and with the latest service packs.2) I did tested version 3.1.3 and then 3.2.1. Always same problem.3) The trace I posted is exactly the trace at the moment of the crash.

Were can I publish all the instructions, you will need license codes and a special version of the Addin (right now the addin extract the dll from the resources) and the crash require a way to hook excel or it will close and crash before you will be able to hook the process in debug mode. If you like this solution I will send you a mail directly from our internal case.

You can email me the instructions and any links to the necessary files to wyatt@wyday.com.