首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ComAddin.Object.SomeMethod在一个项目中工作,而在另一个项目中不工作。

ComAddin.Object.SomeMethod在一个项目中工作,而在另一个项目中不工作。
EN

Stack Overflow用户
提问于 2016-05-10 11:12:57
回答 1查看 480关注 0票数 2

不久前,我做了一个原型,使用VSTO并将其方法公开给另一个项目。

现在,我试图实现我当时成功地使用我目前正在进行的一个项目,但它不起作用。

我收到了一条异常消息"System.__ComObject enth lt keine Definition für Open“,在英语中,这句话的意思与ComObject中没有定义一样多。

我在这里做错什么了?

我检查了拼写错误,引用,如果我忘了实现什么,我对原型做了什么,但没有成功。

最初,我被指给出了我在这个答案中的实现方式:

https://stackoverflow.com/a/35555413/3664953

虽然包含的链接非常棒,并且确实有助于VSTO的工作,但我在这里看不到解决我的特定问题的方法。此外,我也检查了问题,这个答案指出:

https://stackoverflow.com/a/3690214/3664953

我尝试使用x86编译的二进制文件,并在没有更改的情况下将框架从4.5.2改为4.5。

欧罗:好的,行为有变化,x64编译的回收箱(我通常使用“任意CPU")在ComAddIn的对象中有一个null .

我不知道这种行为是在哪里发生的,但也许你知道。

最后,什么是一个已经很糟糕的问题,可能只是因为我离得太近,没有看到错误,没有被破坏的代码。

在这里,我从工作原型开始,还包括新代码。我剪了一点,所以现在这两种解决方案中都只有Open方法。

我这么做了,因为我知道这个问题已经非常长了,我不想浪费你太多的时间。

原型如下所示:

控制者:

代码语言:javascript
复制
static void Main(string[] args)
{
  Microsoft.Office.Interop.Word.Application wd = 
    new Microsoft.Office.Interop.Word.Application();
  wd.Visible = false;
  object addinName = "Worker_AddIn";
  foreach (Microsoft.Office.Core.COMAddIn comaddin in wd.COMAddIns)
  {
    if (comaddin.ProgId.Equals(addinName.ToString(), 
           StringComparison.InvariantCultureIgnoreCase))
    {
      object addinObj = comaddin.Object;
      object[] invokeArgs = { "Dummy" };

      object retVal = 
                    addinObj.
                        GetType().
                        InvokeMember("Open", System.Reflection.BindingFlags.InvokeMethod, 
                        null, addinObj, invokeArgs);

      //dynamics ...
      var t1 = comaddin.Object.Open("Dummy");
      var t2 = comaddin.Object.GetCustomProperties();
      var t3 = comaddin.Object.SetCustomProperty("Test",
                 PropertyTypes.msoPropertyTypeBoolean, 42);
    }
  }
  //Properly close Word
  wd.Quit();
}

AddIn:

PropertyReaderWriter及其接口:

代码语言:javascript
复制
public enum WordBuiltinProperties
{
  //some enums
}

public enum PropertyTypes
{
  //more enums
}

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IPropertyReadWriter
{
  bool Open(string Path);
  //There are more methods, but this one is already causing problems, 
  //also the others don't work either, so I kept the simplest one ;)
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class PropertyReaderWriter : StandardOleMarshalObject, IPropertyReadWriter
{
  public bool Open(string Path)
  {
    return false;
    //This was a test, if I could actually use those methods outside of VSTO, 
    //so I didn't implement logic, since I know the stuff I need works in VSTO.
  }
}

AddIn覆盖RequestComAddInAutomationService():

代码语言:javascript
复制
private IPropertyReadWriter rw;

protected override object RequestComAddInAutomationService()
{
  if (rw == null)
    rw = new PropertyReaderWriter();
  return rw;
}

课程课程:

代码语言:javascript
复制
Microsoft.Office.Interop.Word.Application wd = 
  new Microsoft.Office.Interop.Word.Application();
wd.Visible = false;
object addinName = "Worker_AddIn";
foreach (Microsoft.Office.Core.COMAddIn comaddin in wd.COMAddIns)
{
  if (comaddin.ProgId.Equals(addinName.ToString(), 
       StringComparison.InvariantCultureIgnoreCase))
  {
    object addinObj = comaddin.Object;
    object[] invokeArgs = { "Dummy" };
    object retVal = addinObj.
                     GetType().
                     InvokeMember("Open", System.Reflection.BindingFlags.InvokeMethod, 
                                  null, addinObj, invokeArgs);
    //dynamics ...
    var t1 = comaddin.Object.Open("Dummy");
    var t2 = comaddin.Object.GetCustomProperties();
    var t3 = comaddin.Object.SetCustomProperty("Test", PropertyTypes.msoPropertyTypeBoolean,
                                               42);
  }
}
//Properly close Word
wd.Quit();

我项目中的实现如下所示。

有了这个接口,我就有了一个名为IPropertyReadWrite_Word的派生接口,在这里我添加了更多的方法,我不覆盖。另外,我在最后的实现中使用了IPropertyReadWrite_Word,但是由于这个接口定义了"Open“,所以我只发布它来缩短极长的post。

接口:

代码语言:javascript
复制
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IPropertyReadWrite_Common
{
  /// <summary>
  /// Soll die Datei am entsprechenden Pfad öffnen.
  /// </summary>
  /// <param name="Path">Pfad zur Datei</param>
  /// <returns>Gibt Erfolg/true oder Misserfolg/false zurück.</returns>
  bool Open(string Path);
}

AddIn中的实现:

代码语言:javascript
复制
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class Word_PropertyReadWrite : StandardOleMarshalObject, IPropertyReadWrite_Word
{
  internal static Word.Document Document;
  internal ThisAddIn home;

  /// <summary>
  /// Erzeugt die Klasseninstanz.
  /// </summary>
  /// <param name="home">Übergibt das ThisAddIn-Objekt, 
  /// um die Funktionen von Word verwenden zu können.</param>
  public Word_PropertyReadWrite(ThisAddIn home)
  {
    this.home = home;
  }

  /// <summary>
  /// Öffnet die Datei am entsprechenden Pfad.
  /// </summary>
  /// <param name="Path">Pfad zur Datei</param>
  /// <returns>Gibt bei Erfolg true zurück.</returns>
  public bool Open(string Path)
  {
    try
    {
        Document = home.Application.Documents.OpenNoRepairDialog(FileName: Path,
            ConfirmConversions: false, ReadOnly: false, AddToRecentFiles: false,
            Revert: false, Visible: false, OpenAndRepair: true, NoEncodingDialog: false);
        return true;
    }
    catch
    {
        //TODO: Logging
        //Rethrow der entstandenden Exception.
        throw;
    }
  }
}

RequestComAddInAutomationService()的重写:

Word_PropertyReadWrite PropertyReadWrite;

代码语言:javascript
复制
protected override object RequestComAddInAutomationService()
{
  //System.Diagnostics.Debugger.Break();
  if (PropertyReadWrite == null)
    PropertyReadWrite = new Word_PropertyReadWrite(this);
  return PropertyReadWrite;
}

最后,到目前为止,这是我的考试课:

代码语言:javascript
复制
static void Main(string[] args)
{
  Microsoft.Office.Interop.Word.Application wd = 
    new Microsoft.Office.Interop.Word.Application();
  wd.Visible = false;
  object addinName = "Dokumentenvorbereitung_Word_AddIn";
  try
  {
    Microsoft.Office.Core.COMAddIn addin = 
      wd.COMAddIns.Item(ref addinName);
    foreach (Microsoft.Office.Core.COMAddIn comaddin in wd.COMAddIns)
    {
      if (comaddin.ProgId.Equals(addinName.ToString(),
          StringComparison.InvariantCultureIgnoreCase))
      {
        var test = (comaddin).Object.Open(@"Path to some valid .docx");
      }
    }
  }
  catch(Exception e)
  {
    //...
  }
  finally
  {
    wd.Quit();
  }
}
EN

回答 1

Stack Overflow用户

发布于 2016-05-11 13:33:03

嗯,我找到了一个解决方案,这有点奇怪,我在实现中添加了IPropertyReadWrite_Word的父接口,称为IPropertyReadWrite_Common。

现在我的标题是这样的:

代码语言:javascript
复制
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class Word_PropertyReadWrite : StandardOleMarshalObject, IPropertyReadWrite_Common,
    IPropertyReadWrite_Word

现在它就像一种魅力,虽然我不确定,为什么它一开始就不起作用.也许有人能加个提示?

这是一种奇怪的行为,我有点怀疑,在不久的将来,任何人都会有同样的问题,因为我的用例是相当.奇数:)

在这一点上,我真的想感谢@辛迪梅斯特,你已经两次帮助我用这样一个奇怪的问题,谢谢你的耐心!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37136891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档