如何从其他c#项目

时间:2016-02-22 12:17:23

标签: c# vsto ms-office

在我的解决方案中,我有2个项目。

一个是控制器,在最终产品中用于检查是否从控制台/非用户输入发出执行,因此将基于来自xml文件的输入执行所需的后台更改,或者执行由用户输入发出,这将打开一个界面。

非用户输入可能是一个计划任务或类似的东西,但那已经是另一个时间了,我只是在某些情况下编写它。

在这两种情况下,迟早都需要访问word文档以及读取,写入和更改文档属性。

为此,我创建了一个带有所需功能的VSTO-Word-Addin,到目前为止,我对路径进行了硬编码,并且没有将结果返回到其他文档以外的其他地方。

由于我确信我的VSTO代码本身有效,我想将原型扩展到下一级并尝试在控制台和VSTO之间添加连接。

为了测试我稍微简化了一下这个过程,只是尝试在没有任何用户输入的情况下建立控制台和VSTO之间的连接,并尝试执行一些方法来测试我的VSTO的功能。

我的方法是打开控制台,然后打开Word /插件,打开隐藏的文件并做魔术。

要做的第一件事是设置要打开的文档的路径,然后使用返回的值调用多个方法。

在这种情况下,我的VSTO为

返回true
SetCustomProperty 

的新元组列表
GetCustomProperties

这些是占位符,将在开发中被替换。

我已经尝试了一些可能的解决方案,但是其中大多数都是从VSTO启动WinForms / WPF / Console或尝试从其AddIn调用其他AddIn。

我最成功的方法就是这个:

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

但当然这是办公室所以我遇到了无法使用

的问题
Globals

有关Globals的更多信息,请访问here in MSDN

所以也许我错过了这一点并且只是盲目的,但我如何从控制台调用VSTO项目中的类?

以下是我当前失败的一些代码示例:

具有我想要访问的已使用接口的类:

[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;
  }
}

MSDN文章中关于从其他办公室项目调用的代码:

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

我不知道如何使用它,因为我无法访问VSTO外的Globals?

因为缺乏上下文或示例,所以我可以使用没有答案的类似问题:

我不知道DanByström的回答是什么意思,而Mike Regan的回答也导致了之前陈述的MSDN。

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

2 个答案:

答案 0 :(得分:2)

首先,向要调用的Addin添加一个接口:

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

接下来,添加一个实现接口的类:

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

然后在ThisAddin.cs:

中覆盖对象RequestComAddInAutomationService
private AddInUtilities utilities;

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

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

现在您应该能够从外部应用程序中调用公开的方法,如下所示:

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

有关此主题的更深入信息,另请阅读: http://blogs.msdn.com/b/andreww/archive/2008/08/11/why-your-comaddin-object-should-derive-from-standardolemarshalobject.aspx

希望它有所帮助: - )

答案 1 :(得分:0)

这不是一个确切的答案,但是对于遇到此问题的其他人,document-level solutions cannot expose interfaces to other solutions

  

将VSTO外接程序中的对象暴露给其他Microsoft Office解决方案。