不久前,我做了一个原型,使用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方法。
我这么做了,因为我知道这个问题已经非常长了,我不想浪费你太多的时间。
原型如下所示:
控制者:
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及其接口:
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():
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();我项目中的实现如下所示。
有了这个接口,我就有了一个名为IPropertyReadWrite_Word的派生接口,在这里我添加了更多的方法,我不覆盖。另外,我在最后的实现中使用了IPropertyReadWrite_Word,但是由于这个接口定义了"Open“,所以我只发布它来缩短极长的post。
接口:
[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中的实现:
[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;
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();
}
}发布于 2016-05-11 13:33:03
嗯,我找到了一个解决方案,这有点奇怪,我在实现中添加了IPropertyReadWrite_Word的父接口,称为IPropertyReadWrite_Common。
现在我的标题是这样的:
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class Word_PropertyReadWrite : StandardOleMarshalObject, IPropertyReadWrite_Common,
IPropertyReadWrite_Word现在它就像一种魅力,虽然我不确定,为什么它一开始就不起作用.也许有人能加个提示?
这是一种奇怪的行为,我有点怀疑,在不久的将来,任何人都会有同样的问题,因为我的用例是相当.奇数:)
在这一点上,我真的想感谢@辛迪梅斯特,你已经两次帮助我用这样一个奇怪的问题,谢谢你的耐心!
https://stackoverflow.com/questions/37136891
复制相似问题