简体   繁体   English

为什么接口IMsoErrorBars没有注册为COM接口?

[英]Why is the interface IMsoErrorBars not registered as COM interface?

When using the ErrorBars property in Microsoft.Office.Core.IMsoSeries using COM automation, I get a COM exception "Interface not registered" while it works fine using the property within an add-in. 在使用COM自动化的Microsoft.Office.Core.IMsoSeries中使用ErrorBars属性时,出现COM异常“未注册接口”,但使用外接程序中的属性可以正常工作。

I noticed that the interface IMsoErrorBars is not registered in Windows Registry like all other Office API interfaces are (or at least the ones if have been using so far). 我注意到接口IMsoErrorBars没有像所有其他Office API接口一样在Windows注册表中注册(或者至少到目前为止已经使用过)。 I checked several machines with Office 2010 or 2013 installed and they all missed the IID {000C1721-0000-0000-C000-000000000046} in HKEY_CLASSES_ROOT\\Interface . 我检查了几台装有Office 2010或2013的计算机,它们都错过了HKEY_CLASSES_ROOT\\Interface的IID {000C1721-0000-0000-C000-000000000046}

Does anybody know why it's missing? 有人知道为什么会丢失吗?

UDPATE UDPATE

Here's as example in C# ... 这是C#中的示例...

IEnumerable<int> ErrorBarsColors(Microsoft.Office.Interop.PowerPoint.Shape shape)
{
    var seriesCollection = shape.Chart.SeriesCollection() as IEnumerable;

    foreach (Microsoft.Office.Core.IMsoSeries series in seriesCollection)
    {
        if (series.HasErrorBars)
        {
            var errorBars = series.ErrorBars;
            yield return errorBars.Format.Line.ForeColor.RGB;
        }
    }
}

... that fails with the mentioned COM exception at the series.ErrorBars access when it's called in a stand-alone application using some code like this: ...在系列中由于提到的COM异常而失败。使用类似下面的代码在独立应用程序中调用ErrorBars时会访问它:

var application = new Microsoft.Office.Interop.PowerPoint.Application();
var presentation = application.Presentations.Open(SOME_PRESENTATION);
var shape = presentation.Slides[1].Shapes[1];
var colors = ErrorBarsColors(shape);

But the same code works perfectly when using it in a PowerPoint Add-In. 但是,在PowerPoint加载项中使用相同的代码时,它们可以完美地工作。

Meanwhile I found some other interfaces that neither are registered and show the same behavior. 同时,我发现了一些其他接口,它们均未注册并且显示相同的行为。

The fact that the interfaces are not registered makes them unable to work for calls across apartments (the COM objects could use custom marshaling, but in this case, it seems they don't). 接口未注册的事实使它们无法跨公寓调用(COM对象可以使用自定义封送处理,但在这种情况下,似乎没有)。 It works when you use it as an add-in because it's running in the same apartment (at least, that's my wild guess). 当您将其用作外接程序时,它可以工作,因为它在同一套公寓中运行(至少,这是我的猜测)。

You may want to register the interfaces yourself in HKCR\\Interface\\{IID} with key ProxyStubClsid32 having a default value of {00020424-0000-0000-C000-000000000046} (the universal marshaler that looks up for the interface definition in a typelib) and the key TypeLib having a default value of {2DF8D04C-5BFA-101B-BDE5-00AA0044DE52} and a Version value with the installed Office typelib version, such as 2.3 for 2003, 2.4 for 2007, 2.5 for 2010, 2.6 and 2.7 for Office 2013 (look for point 8). 你可能想自己注册的界面在HKCR\\Interface\\{IID}与关键ProxyStubClsid32具有缺省值{00020424-0000-0000-C000-000000000046}通用封送看起来弥补了接口定义的类型库)以及具有默认值{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}和已安装Office typelib版本的Version密钥的TypeLib ,例如2003的 {2DF8D04C-5BFA-101B-BDE5-00AA0044DE52} 和2.7的Office 2013 (请看第8点)。 It shouldn't matter which, the interface should remain the same between versions. 不管哪个版本之间的接口都应该保持不变。

But that doesn't make it right, the underlying operations may require some sort of same-apartment, hence in-process, data access. 但是,这样做并不对,底层操作可能需要某种相同的单元,因此需要进行进程中的数据访问。 With a separate process, you may be violating both assumptions. 使用单独的过程,您可能会违反两个假设。 It's better to contact Microsoft and ask if this is a bug or an unintended omission. 最好与Microsoft联系,并询问这是Bug还是意外遗漏。 Or just try it out, with the risk of falling prey to the "it works on my machine" phenomenon. 或者只是尝试一下,否则可能会遭受“它在我的机器上工作”现象的威胁。

The sure way around is to have the Office application create an object to which you can dispatch calls to the ErrorBars property given a Series object. 确定的方法是让Office应用程序创建一个对象,可以ErrorBarsSeries对象的对ErrorBars属性的调用ErrorBars给该对象。 Maybe have an add-in for it, since you've already tried and it worked. 也许有一个插件,因为您已经尝试过并且可以使用。

Not all COM interfaces are registered. 并非所有COM接口都已注册。 Only COM interfaces that can be directly created via CoCreateInstance have to be registered. 仅可以注册可通过CoCreateInstance直接创建的COM接口。 If the COM interface is obtained from some other method (in this case, from the ErrorBars property), it does not have to be registered. 如果COM接口是从其他方法(在这种情况下,是从ErrorBars属性)获得的,则不必注册它。

There is no mandatory registration for COM interfaces. COM接口没有强制注册。 Those mentioned in registry under HKEY_CLASSES_ROOT\\Interface\\{CLSID} are typically interfaces that either require/use custom proxy/stub handlers, or registered along with registration of type library which contains them. 注册表中在HKEY_CLASSES_ROOT\\Interface\\{CLSID}下提到的那些HKEY_CLASSES_ROOT\\Interface\\{CLSID}通常是需要/使用自定义代理/存根处理程序的接口,或者与包含它们的类型库的注册一起注册的接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM