ExcelDna icon indicating copy to clipboard operation
ExcelDna copied to clipboard

Expose `ExcelDnaUtil.IsApplicationOK` (or similar) (?)

Open augustoproiete opened this issue 4 years ago • 9 comments

Continuation of discussion from #267.

When would it make sense for an add-in developer to want to call ExcelDnaUtil.IsApplicationOK?

Does it make sense to expose ExcelDnaUtil.IsApplicationOK (or similar) to developers?

https://github.com/Excel-DNA/ExcelDna/blob/c38f1b914a6e68a513e7c5b1cc2387783e727bf8/Source/ExcelDna.Integration/Excel.cs#L486-L502


Calling the COM object model from the main thread in a context where COM calls are not handled, often results in COM errror 0x800A03EC (which I've seen documented as NAME_NOT_FOUND).

What are common scenarios that could cause the behavior above?


Relates to #265, #171, #172.

augustoproiete avatar Nov 02 '19 05:11 augustoproiete

Calling the COM object model from the main thread in a context where COM calls are not handled, often results in COM errror 0x800A03EC (which I've seen documented as NAME_NOT_FOUND).

What are common scenarios that could cause the behavior above?

If you (possibly implicitly) hook into the Windows message loop (e.g. by running a timer that fires through the message loop) and Excel is in a state where it is processing messages on the main thread (e.g, the user is editing a formula) then you can find this error because Excel suspends the object model. Excel does not seem to comply with the standard COM mechanisms, so implementing IMessageFilter etc. does not work for this case with Excel.

govert avatar Nov 02 '19 07:11 govert

@augustoproiete I don't understand this code, why is it calling Version?

fandrei avatar Nov 02 '19 18:11 fandrei

@fandrei It's calling a safe property on the Application object as a check to see it the COM object is accessible or not. In your add-in code you can call ExcelDnaUtil.Application (which internally does the IsApplicationOK check) and know that you're safe in the current context. But you are safe to talk to the COM object model in:

  • Macro contexts, like the AutoOpen of your add-in, or any public void method that is registered with Excel as a macro and is called from the Excel side.
  • Inside the ExcelAsyncUtil.QueueAsMacro context
  • Ribbon callback events and other COM add-in event handlers
  • Event handlers on COM object

Bad places are calls which originate from elsewhere - another thread, an event from other UI elements like a Form you're showing etc.

The lists aren't exhaustive.

govert avatar Nov 02 '19 18:11 govert

There are some more notes here: https://github.com/Excel-DNA/ExcelDna/wiki/COM-object-model-notes

govert avatar Nov 02 '19 18:11 govert

Hi govert!

I have to object against the third bullet, I experienced bad problems when starting work triggered by a ribbon callback, however being in the middle of a cell/formula edit. I circumvented this by a hack I found on https://www.add-in-express.com/creating-addins-blog/2011/03/23/excel-check-user-edit-cell/: ExcelDnaUtil.Application.CommandBars.GetEnabledMso("FileNewDefault")

This however strongly depends on Microsofts benevolence to not change the GUI (and it won't work with Excel<2010), so I really think the IsApplicationOK would come here handy.

rkapl123 avatar Mar 06 '20 15:03 rkapl123

@rkapl123 Your check is far more refined than the internal IsApplicationOK we're discussing here. You're successfully using the Application object to do your check, so the COM object model is indeed 'alive' in the editing context if the action is initiated by a ribbon press. But you find other features of Excel (like writing to the sheet) are restricted.

It's a fair point that one might have some extra helpers available for different scenarios. But I don't know enough about these issues to know what implementation has value inside Excel-DNA vs. what you can just put in your add-in yourself (like the example you show).

govert avatar Mar 06 '20 15:03 govert

@govert Well, I thought after you mentioned "and Excel is in a state where it is processing messages on the main thread (e.g, the user is editing a formula).." that might be such a case where Excel is not ready to process my COM calls.

rkapl123 avatar Mar 06 '20 16:03 rkapl123

@rkapl123 I think if you're able to call Application.CommandBars.GetEnabledMso("FileNewDefault") then Excel is indeed ready to process your COM calls. The problem seems to be that there are different notions of "OK" for the state Excel can be in. I don't have a good grip on these. Hence I want to leave the IsApplicationOK check as an internal implementation helper, and might change the interpretation of "OK" in future.

govert avatar Mar 06 '20 16:03 govert

I've seen also another case where Excel is not quite so ready, being in a UDF which calls another procedure in ExcelAsyncUtil.QueueAsMacro context. There, it's forbidden to set the Calculation to something different. Right now, detecting this is only possible with catching the Application.Calulation setting error.

rkapl123 avatar Mar 06 '20 18:03 rkapl123