I have had this question a number of times and surprised myself when I did not see it in my blog. So here goes.
There are times when (like my Master Add-in Entry), you need to expose a set of methods or properties in your add-in so that other add-ins or applications are able to access them. Here is how it is done:
1) You create an interface and a class that uses that interface, like this:
[ComVisibleAttribute(true)] public interface IExposedMethods { void LoadDocument(string path); } [ComVisibleAttribute(true)] [ClassInterface(ClassInterfaceType.None)] public class ExposedClass : IExposedMethods { public void LoadDocument(string path) { Globals.ThisAddIn.Application.Workbooks.Open(path); } }
2) Next, you need to add the following code to your ThisAddin.cs:
private ExposedClass _exposedInstance; protected override object RequestComAddInAutomationService() { if (_exposedInstance == null) _exposedInstance = new ExposedClass(); return _exposedInstance; }
3) And finally, to call it and access this from another application instance, you do this:
Excel.Application xlApp = new Excel.Application(); xlApp.Visible = true; object addinName = "MyAddinName"; Office.COMAddIn addIn = xlApp.COMAddIns.Item(ref addinName); addIn.Object.LoadDocument(@"c:\path\test.xlsm");
It is actually quite easy to implement. And the beauty here is that the ExposedClass you created can have all sorts of methods and properties that are exposed. And because the _exposedInstance is global to ThisAddIn (via Globals.ThisAddin._exposedInstance), you can access it anywhere. So it is a perfect way for one add-in to contact another or for a parent Windows Form application to reach into the Add-in and set properties and call methods and have it open documents and such for you.
[…] this example, we will be building upon my previous post on exposing methods using the RequestComAddInAutomationService callback. First, you need to create a Word Template […]
Hello
And how it will be the same thing but for a WorkBook?
(VS2012 with an Office 2010 Workbook, then also InteropServices)
I am not sure I follow the question. Are you asking about a Workbook Project (Document-level solution)? If so, I do not believe this method will work. I am not sure how a document level solution would be exposed in the running instance since it is not really, at its base, an extensibility project.
Hello again
Thanks for your answer
I am just starting with VSTO, before I did few things with interop services.
Just a WPF app over workbooks.
So I was looking for a fast way (that does not exist)
Regards
too bad this only works with an application-level add-in. I have been trying to figure out if it is possible to expose a C# class to VBA in a document-level add-in for a while now and I am unable to.
If interested or know the solution please see http://stackoverflow.com/questions/22787956/how-to-expose-a-c-sharp-class-to-a-vba-module-in-a-document-level-add-in
Looks nice and simple but I’m facing “No such interface supported” error and no fix I found worked.
There are prconditions/versions required?
Not sure why you would be getting that error. When you get an interface error it would imply that the exposed class is not visible for some reason. It has been about 10 years since I have used this, so a couple of things come to mind. The first is that there is some degree of isolation built into Office add-ins now. Or there is some difference in 32bit versus 64bit memory addresses that might not work right in 64bit Office these days. Or it is a security feature or some other component blocking your access to the object. Not sure if anyone else has attempted anything like this recently, but my suggestion is to research the ComVisible options or the try different Interface types. If all else fails — and this is an uglier solution but found it worked too. You can have both add-ins watch a file or a registry key, and they communicate through that to send messages and activate operations.