This project has moved and is read-only. For the latest updates, please go here.

ProxyCount problem when creating CommandBarButton

Aug 17, 2012 at 7:45 PM
Edited Aug 17, 2012 at 7:46 PM

When running the following test code, the output for Proxy Count is 1,5,0.

Q1: It seems creating the commandBarButton increases the ProxyCount by 4. Why does this happen?

Q2: After _app.Dispose(), ProxyCount is reduced to 0. But the ContextClick event does not take effect. If _app.Dispose() is removed, ContextClick event takes effect. Is it necessary to call _app.Dispose?

Excel.Application _app = new Excel.Application(null, ExcelDnaUtil.Application);
Debug.WriteLine(Factory.ProxyCount);

Office.CommandBarButton commandBarButton = (Office.CommandBarButton)_app.CommandBars["Cell"].Controls.Add(
MsoControlType.msoControlButton,
System.Type.Missing, //id
System.Type.Missing, //parameters
System.Type.Missing,
true);
commandBarButton.Caption = "TestButton";
Debug.WriteLine(Factory.ProxyCount);

commandBarButton.ClickEvent += new Office.CommandBarButton_ClickEventHandler(ContextClick);

_app.Dispose();
Debug.WriteLine(Factory.ProxyCount);

Aug 17, 2012 at 10:12 PM

hello,

let me explain.

_app.CommandBars                                        // commandbars is the first proxy
CommandBars["Cell"]                                      // cell is the second proxy
_app.CommandBars["Cell"].Controls                 // controls is the third proxy
Office.CommandBarButton commandBarButton // the returning object is your last proxy

you have to know:
every time you call _app.CommandBars you get a new proxy for the commandbars object on the COM server(Office)
you have to free all proxies at hand with the ms-interop assemblies to avoid memory leaks but its easier in NetOffice.
In your example, NetOffice store the proxies in a table as follows:

 app
   + CommandBars
       + Cel
            + Controls
                  + Button

if you call Dispose() for the application then NetOffice dispose the app proxy( Marshal.ReleaseComObject) and all descendent proxies to avoid memory leaks.
Dispose have an overload Dispose(bool disposeEventBinding) you can use Dispose(false) but this is an unsafe way(not supported from all office apps in any version)

of course the event trigger doesnt works when you free the COM proxy. dispose the proxy at the end of your application lifecycle.

Sebastian