gpt4 book ai didi

c# - ComAddin.Object.SomeMethod 在一个项目中有效,但在另一个项目中无效

转载 作者:太空宇宙 更新时间:2023-11-03 15:21:37 24 4
gpt4 key购买 nike

我前段时间做了一个原型(prototype),使用 VSTO 并将其方法公开给其他项目。

现在,我尝试将我当时的成功使用实现到我目前正在从事的项目中,但它不起作用。

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

我在这里做错了什么?

我检查了拼写错误、引用,如果我忘记实现我对原型(prototype)所做的事情,但没有成功。

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

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

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

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

我尝试使用 x86 编译的二进制文件,并将框架从 4.5.2 切换回 4.5,没有任何变化。

€:嗯,好的,行为发生了变化,x64 编译的容器(我通常使用“任何 CPU”)在 ComAddIn 的对象中有一个 null ...

我真的不知道这种行为起源于何处,但也许你知道。

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

就是这样,我从工作原型(prototype)开始,还包括新代码。我删减了一点,所以现在两个方案都只有Open-method了。

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


原型(prototype)看起来像这样:

Controller :

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();
}

加载项:

PropertyReaderWriter 及其接口(interface):

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.
}
}

RequestComAddInAutomationService() 的加载项覆盖:

private IPropertyReadWriter rw;

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

程序类:

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();

我项目中的实现是这样的。

有了接口(interface),我有一个派生接口(interface),称为 IPropertyReadWrite_Word,我在其中添加了更多方法,但我没有覆盖。我还使用 IPropertyReadWrite_Word 作为我的最终实现,但由于它是这个接口(interface),它定义了“打开”,我只发布它来缩短极长的帖子。

接口(interface):

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

插件中的实现:

[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() 的覆盖:

私有(private)Word_PropertyReadWrite PropertyReadWrite;

protected override object RequestComAddInAutomationService()
{
//System.Diagnostics.Debugger.Break();
if (PropertyReadWrite == null)
PropertyReadWrite = new Word_PropertyReadWrite(this);
return PropertyReadWrite;
}

最后,这是我到目前为止的测试类:

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();
}
}

最佳答案

好吧,我找到了一个解决方案,它有点奇怪,我在实现中添加了 IPropertyReadWrite_Word 的父接口(interface),称为 IPropertyReadWrite_Common。

现在我的标题看起来像这样:

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class Word_PropertyReadWrite : StandardOleMarshalObject, IPropertyReadWrite_Common,
IPropertyReadWrite_Word

现在它就像一个魅力,虽然我不确定,为什么它不应该开始工作......也许有人可以添加一个提示?

这是一个非常奇怪的行为,我有点怀疑,在不久的将来任何人都会遇到同样的问题,因为我的用例非常......奇怪:)

在这一点上,我真的要感谢@Cindy Meister,你已经两次帮助我解决了这么奇怪的问题,感谢你的耐心等待!

关于c# - ComAddin.Object.SomeMethod 在一个项目中有效,但在另一个项目中无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37136891/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com