standardolemarshalobject

standardolemarshalobject

本文介绍了VSTO加载项,COMAddIns和RequestComAddInAutomationService的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请参阅第一个编辑(底部的屏幕截图):



我已按照此文章使Winform应用触发VSTO加载项方法:



在上面的文章结束时,作者提到一个问题,并尝试在这里改进它:



我已通过代码多次现在和导出StandardOleMarshalObject以改善异常的方法不起作用



System.InvalidCastException:无法将类型为System .__ ComObject的COM对象转换为接口类型...此操作失败,因为COM组件上的QueryInterface调用与IID



这里是两个项目目标.Net 3.5:



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

 命名空间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)
{
}
}
}

类加载到Excel加载项:

 命名空间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);
}
}
}

Build> 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)运行Winform应用程序, c $ c> utils =(IAddinUtilities)addin.Object; 失败,无论AddinUtilities是否派生自StandardOleMarshalObject。



由于MSDN Blog明确地说:要解决这一切,你可以从StandardOleMarshalObject派生AddinUtilities类,并重建:

p>

1st EDIT:我尝试在另一个PC-B上的代码,它的工作原理不是从 StandardOleMarshalObject



当我在PC-B上使用 StandardOleMarshalObject 时,我遇到了与PC-A相同的问题。 PC-A不工作与任何方式,唯一的区别,我可以想到的是管理员权限。



>



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

解决方案

当设置注册Com interop 我发现你需要以管理员身份运行 / p>

如果没有管理员尝试编译,我会收到以下错误:

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



解决方案



关闭注册COM interop并且错误消失 - 但是这导致它不工作!



Shift +右键单击Visual Studio并以管理员身份打开该项目。 Tick注册Com互操作,它编译成功,它现在工作在PC-A当从StandardOleMarshalObject - ,但它不工作没有StandardOleMarshalObject - 这是相反的结果,我在PC-B


Please see 1st Edit (the screenshot at the bottom):

I've followed this article to have a Winform app trigger a VSTO Add-In method:http://blogs.msdn.com/b/andreww/archive/2007/01/15/vsto-add-ins-comaddins-and-requestcomaddinautomationservice.aspx

At the end of the above article the author mentions a issue and tries to ameliorate it here:http://blogs.msdn.com/b/andreww/archive/2008/08/11/why-your-comaddin-object-should-derive-from-standardolemarshalobject.aspx

I have been through the code several times now and the method to derive StandardOleMarshalObject to ameliorate the exception does not work!

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

Here is a repro - both projects target .Net 3.5:

a) Create a new Office > 2007 or 2010 > Excel Add-In:

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) Add a class to the Excel Add-In:

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) Set Project Properties > Build > seklect Register For COM Interop. Compile the Add-In.

d) New Winform App, reference the ExcelAddIn1, Microsoft.Office.Interop.Excel and Office and include this code in 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) Run the Winform app and the line utils = (IAddinUtilities)addin.Object; fails regardless of whether or not AddinUtilities derives from StandardOleMarshalObject.

I am at a loss here as the MSDN Blog specifically says: "To fix all this, you can simply derive the AddinUtilities class from StandardOleMarshalObject, and rebuild:"

1st EDIT: I tried the code on another PC-B and it works without deriving from StandardOleMarshalObject,

When I tried with StandardOleMarshalObject on PC-B I got the same problem as PC-A. PC-A doesn't work with either ways and the only difference I can think of is admin rights.

Admin rights and pre-Win7 (old msdn articles) are the only reasons I can think of why it would not work.

解决方案

When setting Register For Com interop I've found that you do need to run as Administrator.

Without Administrator trying to compile I got errors like:

The above registry key didn't exist so I created it, then trying to compile I got:

Solution

Turn off Register for COM interop and the error goes away - but this causes it not to work!

Shift + Right click Visual Studio and open as Administrator, open the project. Tick Register for Com interop and it compiles successfully and it works now on PC-A when deriving from StandardOleMarshalObject - but it doesn't work without StandardOleMarshalObject - which is the opposite results I got on PC-B.

这篇关于VSTO加载项,COMAddIns和RequestComAddInAutomationService的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-06 22:04