How to call VSTO class from other c# project

2020-03-07 04:21发布

In my solution I have 2 projects.

One is the controller, which in the final product is used to check if a execution is issued from console/non user input and therefore will execute the wanted changes in background based on imput from a xml-file, or if the execution was issued by user input, which will open an interface.

A non user input would maybe a planed task or something like that, but thats is for an other time now and I just write that for some context.

In both cases, sooner or later there is the need to access word-documents and read, write and change document-properties.

To do that I created a VSTO-Word-Addin with the needed functions and up to this point I hardcoded the paths and didn't return the results anywhere else than an other document.

Since I am sure my code in VSTO itself works, I wanted to extend the prototype to the next level and tried adding the connections between console and VSTO.

For testing I am simplifying the process a bit and just try to establish the connection between console and VSTO without any userinput and trying to execute some methods to test functionality of my VSTO.

My approach was to open the console, which then opens Word/the addin, open the file hidden and do the magic.

First thing to do is to set a path for the document to be opened and then call multiple methods with returned values.

In this case my VSTO returns a true for

SetCustomProperty 

and a new List of Tuples for

GetCustomProperties

Those are placeholders and will be replaced in developement.

I already tried some possible solutions, but most of them go the other way around to start a WinForms/WPF/Console out of VSTO or try to call an other AddIn from their AddIn.

The approach I had the most success with was this one:

MSDN Calling Code in VSTO Add-ins from Other Office Solutions

But of course this is for office so I hit the problem of not being able to use

Globals

More info about Globals can be found here in MSDN

So maybe I am missing the point and am just blind, but how can I call a class in a VSTO-project from console?


Here are some codesamples of my current failure:

The class with the used interface I want to access:

[ComVisible(true)]
public interface IPropertyReadWriter
{
  bool Open(string Path);

  bool SetCustomProperty(String Name, PropertyTypes Type, object Value);

  List<Tuple<String, PropertyTypes, object>> GetCustomProperties();
}

[ComVisible(true)]
public class PropertyReaderWriter : IPropertyReadWriter
{
  public List<Tuple<string, PropertyTypes, object>> GetCustomProperties()
  {
    return new List<Tuple<string, PropertyTypes, object>>();
  }

  public bool Open(string Path)
  {
    return false;
  }

  public bool SetCustomProperty(string Name, PropertyTypes Type, object Value)
  {
    return false;
  }
}

The code used in the MSDN article about calling from other office-project:

object addInName = "ExcelImportData";
Office.COMAddIn addIn = Globals.ThisAddIn.Application.COMAddIns.Item(ref addInName);
ExcelImportData.IAddInUtilities utilities = (ExcelImportData.IAddInUtilities)addIn.Object;
utilities.ImportData();

I dont know how to make use of this, because I don't have access to Globals outsite of VSTO?

Somewhat similar question on so with no answer I could use, because lack of context or example:

I don't know what Dan Byström meant with his answer, also Mike Regan's answer lead to prior stated MSDN.

How to call a VSTO AddIn method from a separate C# project?

2条回答
唯我独甜
2楼-- · 2020-03-07 04:48

This isn't an answer exactly, but for others coming across this, document-level solutions cannot expose interfaces to other solutions.

Expose an object in a VSTO Add-in to other Microsoft Office solutions.

查看更多
唯我独甜
3楼-- · 2020-03-07 04:49

First, to your Addin that you want to call into add an Interface:

[ComVisible(true)]
public interface IExcelUtilities
{
    bool DoSomething();
}

Next, add a class that implements the interface:

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class AddInUtilities : 
    StandardOleMarshalObject,
    IExcelUtilities
{
    public bool DoSomething()
    {
        return true;
    }
}

Then override object RequestComAddInAutomationService in ThisAddin.cs:

private AddInUtilities utilities;

protected override object RequestComAddInAutomationService()
{
   try
   {
       if (utilities == null)
       {
           utilities = new AddInUtilities();
       }

       return utilities;
    }
    catch (System.Exception ex)
    {
         // Catch your ex here
    }
}

Now you should be able to call the exposed method from your external application like this:

foreach (COMAddIn comaddin in addins)
{
     if (comaddin.ProgId.Equals("YourAddinNameHere", StringComparison.InvariantCultureIgnoreCase) == true)
     {
              bool returnvalue = comaddin.Object.DoSomething();
              break;
     }
}

for some more deep info on this subject, also read: http://blogs.msdn.com/b/andreww/archive/2008/08/11/why-your-comaddin-object-should-derive-from-standardolemarshalobject.aspx

Hope it helps :-)

查看更多
登录 后发表回答