VSTO加载项,COMAddIns和RequestComAddInAutomationService

请参阅1st Edit (底部的屏幕截图):

我已经按照本文的说法让Winform应用程序触发VSTO加载项方法: http : //blogs.msdn.com/b/andreww/archive/2007/01/15/vsto-add-ins-comaddins-and -requestcomaddinautomationservice.aspx

在上面的文章的最后,作者提到了一个问题,并试图在这里改进它: http : //blogs.msdn.com/b/andreww/archive/2008/08/11/why-your-comaddin-object-should -derive从- standardolemarshalobject.aspx

我现在已经多次通过代码,并且派生StandardOleMarshalObject以改善exception的方法不起作用

System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to interface type ... This operation failed because the QueryInterface call on the COM component for the interface with IID

这是一个repro – 两个项目的目标.Net 3.5:

a)创建新的Office> 2007或2010> Excel加载项:

 namespace ExcelAddIn1 { public partial class ThisAddIn { private AddinUtilities addinUtilities; protected override object RequestComAddInAutomationService() { if (addinUtilities == null) { addinUtilities = new AddinUtilities(); } return addinUtilities; } private void ThisAddIn_Startup(object sender, System.EventArgs e) { } private void ThisAddIn_Shutdown(object sender, System.EventArgs e) { } } } 

b)将类添加到Excel加载项:

 namespace ExcelAddIn1 { [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface IAddinUtilities { void DisplayMessage(); } [ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] public class AddinUtilities : StandardOleMarshalObject, IAddinUtilities { void IAddinUtilities.DisplayMessage() { MessageBox.Show("Hello World"); } } } 

c)设置项目属性>构建> seklect注册COM Interop。 编译加载项。

d)新的Winform应用程序,引用ExcelAddIn1,Microsoft.Office.Interop.Excel和Office,并在Form1中包含此代码:

 public partial class Form1 : Form { private Microsoft.Office.Interop.Excel.Application excel; private IAddinUtilities utils; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { excel = new Microsoft.Office.Interop.Excel.Application(); excel.Visible = true; excel.Workbooks.Add(Microsoft.Office.Interop.Excel.XlSheetType.xlWorksheet); object addinName = "ExcelAddin1"; COMAddIn addin = excel.COMAddIns.Item(ref addinName); utils = (IAddinUtilities)addin.Object; utils.DisplayMessage(); } } 

e)运行utils = (IAddinUtilities)addin.Object;应用程序和行utils = (IAddinUtilities)addin.Object; 无论AddinUtilities是否派生自StandardOleMarshalObject,都会失败。

我在这里不知所措,因为MSDN博客特别说:“要解决所有这些问题,你可以简单地从StandardOleMarshalObject派生AddinUtilities类,并重建:”

第一次编辑:我在另一台PC-B上尝试了代码,它的工作原理是不使用StandardOleMarshalObject

在此处输入图像描述

当我在PC-B上尝试使用StandardOleMarshalObject ,我遇到了与PC-A相同的问题。 PC-A不适用于任何一种方式,我能想到的唯一区别是管理员权限。

在此处输入图像描述

管理员权限和pre-Win7(旧的msdn文章)是我能想到为什么它不起作用的唯一原因。

设置Register For Com interop 我发现您确实需要以管理员身份运行。

没有管理员尝试编译我得到的错误如下:

无法注册程序集“C:\ TFS \ Project \ Src \ ProjectAddin \ bin \ Debug \ ProjectAddin.dll” – 访问被拒绝。 请确保您以管理员身份运行该应用程序。 访问注册表项“HKEY_CLASSES_ROOT \ CLSID {3A6192EA-3C9C-39EB-99A3-3DBFF8CA118F}”被拒绝。

上面的注册表项不存在所以我创建它,然后尝试编译我得到:

无法注册类型库“C:\ TFS \ Project \ Src \ ProjectAddin \ bin \ Debug \ ProjectAddin.tlb”。 访问OLE注册表时出错。 (来自HRESULT的exception:0x8002801C(TYPE_E_REGISTRYACCESS))

关闭Register for COM interop并且错误消失 – 但这会导致它无法正常工作!

Shift +右键单击Visual Studio并以管理员身份打开,打开项目。 勾选注册Com interop并且它成功编译,当but it doesn't work without StandardOleMarshalObject - which is the opposite results I got on PC-B从StandardOleMarshalObject派生时它现在在PC-A but it doesn't work without StandardOleMarshalObject - which is the opposite results I got on PC-Bbut it doesn't work without StandardOleMarshalObject - which is the opposite results I got on PC-B