【问题标题】:How to call VSTO class from other c# project如何从其他 c# 项目调用 VSTO 类
【发布时间】:2018-08-03 00:21:47
【问题描述】:

在我的解决方案中,我有 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文章中关于从其他office-project调用的代码:

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

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

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

我不知道 Dan​​ Byström 的回答是什么意思,Mike Regan 的回答也导致了之前提到的 MSDN。

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

【问题讨论】:

  • 你很接近......你已经有了接口和类。现在在您的 VSTO 插件中覆盖 RequestComAddInAutomationService 方法(在 ThisAddIn 中),现在您可以从应用程序中调用公开的方法。我在下面输入了一个完整的示例代码来简化它。

标签: c# vsto ms-office


【解决方案1】:

首先,向您要调用的插件添加一个接口:

[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

希望对你有帮助:-)

【讨论】:

  • 你不知道你帮了我多少!该死的,我从上周四开始就在寻找解决方案!像魅力一样工作。
  • 您是否有机会在另一个插件中拥有异步功能,并在“主机”插件中等待它的答案?
  • @Laureant 你找到解决方案了吗?
【解决方案2】:

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

将 VSTO 插件中的对象公开给其他 Microsoft Office 解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-08
    • 2014-10-10
    • 2015-08-01
    • 1970-01-01
    • 2014-12-13
    • 1970-01-01
    • 2018-08-22
    相关资源
    最近更新 更多