【问题标题】:Interop type cannot be embedded. Use the applicable Interface instead. But 'Embed Interop Types' is already false无法嵌入互操作类型。请改用适用的接口。但是“嵌入互操作类型”已经是错误的
【发布时间】:2019-02-02 20:30:05
【问题描述】:

在我当前的 VSIX 项目中,我收到以下错误:

Interop type 'ProjectKinds' cannot be embedded. Use the applicable interface instead

我很自然地搜索了它,几乎所有SO answers 都建议转到项目参考——在我的例子中是 envDTE80——并将“嵌入互操作类型”设置为 false。但是我已经检查过了,它并没有解决问题。

我还检查了“类似”参考(EnvDTE、EnvDTE100 和 EnvDTE90),它们都将“嵌入互操作类型”设置为 false。

我正在尝试做的代码是:

private static string test = ProjectKinds.vsProjectKindSolutionFolder;

编辑 #1:我还检查了 .csproj 并确认该属性为假

<Reference Include="EnvDTE80, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
  <EmbedInteropTypes>False</EmbedInteropTypes>
</Reference>

编辑#2:微软自己似乎提出了一个相当 .. 哈克解决方案作为最后的手段。对我来说似乎并不干净,但它在一天结束时有效。

https://blogs.msdn.microsoft.com/mshneer/2009/12/07/vs-2010-compiler-error-interop-type-xxx-cannot-be-embedded-use-the-applicable-interface-instead/

【问题讨论】:

  • 你能发布这个问题的答案吗?指向 Microsoft 解决方案的链接已损坏

标签: c# visual-studio visual-studio-2017 vsix


【解决方案1】:

Microsoft 博客帖子以防 EDIT #2 中的链接再次断开。

感谢博文作者 Misha Shneerson。

一些用户报告说,当使用 Visual Studio 2010 并在“嵌入互操作类型”设置为 TRUE 的情况下引用互操作程序集时,他们会收到错误消息,即无法嵌入该类型。然后错误会建议使用接口 - 但没有关于从何处获取此接口的其他详细信息。这篇文章旨在解释错误并就界面是什么提供简单的指导。

“嵌入互操作类型”功能的限制之一是嵌入程序集时无法使用类。此限制与服务有关 - 嵌入元数据是安全的,但不是任何可能包含可执行代码的东西(类类型包含元数据和代码,而接口仅包含元数据)。当您尝试从“嵌入互操作类型”设置为 TRUE 的互操作程序集中引用类类型时,编译器会发出警告。但在大多数情况下,您不需要使用互操作程序集中的类,并且需要对代码进行少量调整才能使用 EIT=true 成功编译。

让我们首先解决此错误的最常见情况。我还将解决用户代码使用来自 VSIP 程序集的常量的情况,例如下面的 EnvDTE.Constants / VSLangProj.PrjKind...

在大多数情况下(例如在其中一个 cmets 中指出的使用 UPnPNATClass 的错误),此错误是尝试实例化 COM 对象的代码的结果,例如这里是启动 Excel 的一段代码:

Excel.ApplicationClass xlapp = new Excel.ApplicationClass();

这里可以说 Excel.ApplicationClass 派生自 Excel.Application 接口,甚至可以使用 Excel.Application 接口来实例化 Excel。如下重写此代码会产生完全相同的结果:

Excel.Application xlapp = new Excel.Application();

通常,要将代码更改为使用接口类型而不是类类型,您只需删除“类”后缀并编译代码!另一种查找适用接口是什么的方法——查看类类型的定义。类通常派生自一个或多个接口。查看每个接口的定义 - 其中一个将具有 CoClass 属性,这就是您要查找的接口。

EnvDTE/VSLangProj 的情况有点不同。我相信应该有来自 VSIP 团队的建议,鼓励使用类型嵌入。不幸的是,EnvDTE/VSLangProj 程序集中的某些常量无法嵌入。对于这些,您需要手动将常量的值嵌入到您的项目中。因为这些是抽象类中的常量字段并且永远不应更改 - 这是一个安全的做法。

在 IDE 中,您可以右键单击需要嵌入的值,然后在本地复制和粘贴这些值。

例如,假设我的 C# 代码有这样的代码:

System.Windows.Forms.MessageBox.Show(EnvDTE.Constants.vsDocumentKindText);

编译这段代码时会出现编译错误:

<errors>
'EnvDTE.Constants' does not contain a definition for 'vsDocumentKindText'
Interop type 'EnvDTE.Constants' cannot be embedded. Use the applicable interface instead.
</errors>

在 IDE 中,我将右键单击 vsDocumentKindText 并选择“转到定义”。这将使我看起来像是常量类的定义。我将复制以下行并将其粘贴到我的代码中:

public abstract class Constants
{
     public const string vsDocumentKindText = "{8E7B96A8-E33D-11D0-A6D5-00C04FB67F6A}";
}

然后我将常量类设为“内部”,将类重命名为 EnvDTEConstants。

internal abstract class EnvDTEConstants
{
    public const string vsDocumentKindText = "{8E7B96A8-E33D-11D0-A6D5-00C04FB67F6A}";
}

接下来,我将检查我的代码并将所有出现的 EnvDTE.Constants 更改为 EnvDTEConstants。现在我的代码可以编译了!

System.Windows.Forms.MessageBox.Show(EnvDTEConstants.vsDocumentKindText);

【讨论】:

    猜你喜欢
    • 2015-05-01
    • 2018-12-07
    • 2011-01-29
    • 1970-01-01
    • 2012-02-27
    • 2022-06-17
    • 1970-01-01
    • 2018-06-10
    • 2023-03-04
    相关资源
    最近更新 更多