【问题标题】:VSIX extension for VS2012 not running when debuggingVS2012 的 VSIX 扩展在调试时未运行
【发布时间】:2013-05-07 14:46:19
【问题描述】:

我在 Visual Studio 2012 中创建了一个新的 VSIX 扩展项目,并编写了一个 MEF 分类器(作为测试),它应该简单地突出显示 .mylang 文件中的所有文本。以下是我的 .NET 4.5 代码的相关部分:

internal static class MyLangLanguage
{
    public const string ContentType = "mylang";

    public const string FileExtension = ".mylang";

    [Export(typeof(ClassificationTypeDefinition))]
    [Name(ContentType)]
    [BaseDefinition("code")]
    internal static ContentTypeDefinition MyLangSyntaxContentTypeDefinition = null;

    [Export]
    [FileExtension(FileExtension)]
    [ContentType(ContentType)]
    internal static FileExtensionToContentTypeDefinition MyLangSyntaxFileExtensionDefinition = null;
}

[Export(typeof(IClassifierProvider))]
[ContentType(MyLangLanguage.ContentType)]
[Name("MyLangSyntaxProvider")]
internal sealed class MyLangSyntaxProvider : IClassifierProvider
{
    [Import]
    internal IClassificationTypeRegistryService ClassificationRegistry = null;

    public IClassifier GetClassifier(ITextBuffer buffer)
    {
        return buffer.Properties.GetOrCreateSingletonProperty(() => new MyLangSyntax(ClassificationRegistry, buffer));
    }
}

internal sealed class MyLangSyntax : IClassifier { }

Here is the full code.

这些是我的source.extension.vsixmanifest 文件中的相关部分。根据我在网上找到的建议和类似文件,我添加了对 MPF 和这两个资产的依赖。

<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
    <!-- ... -->
    <Dependencies>
        <Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="4.5" />
        <Dependency d:Source="Installed" Id="Microsoft.VisualStudio.MPF.11.0" DisplayName="Visual Studio MPF 11.0" Version="[11.0,12.0)" />
    </Dependencies>
    <Assets>
        <Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
        <Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%|" />
    </Assets>
</PackageManifest>

我还尝试了 1.0 版清单:

<?xml version="1.0" encoding="utf-8"?>
<Vsix Version="1.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010">
    <!-- ... -->
    <References />
    <Content>
        <MefComponent>|%CurrentProject%|</MefComponent>
    </Content>
</Vsix>

当我运行它时,它会启动 Visual Studio 2012 的实验实例,Extensions and Updates 窗口显示我的扩展处于活动状态。但是,当我加载或创建 .mylang 文件时,它不会做任何事情。我从扩展中抛出(作为测试)的任何异常都不会被抛出。断点永远不会被命中,并会得到一个感叹号,并带有以下警告:

当前不会命中断点。没有为此文档加载任何符号。

感觉好像我的扩展程序根本没有真正加载。我的问题类似于this problemthis problem,但我使用的是使用新的 VSIX 清单格式的 Visual Studio 2012。

我知道的:

  • 我可以在%localappdata%\Microsoft\VisualStudio\11.0Exp\Extensions\MyLang\VSIXProject1\1.0 文件夹中找到我的 DLL 和 VSIX 文件,所以我知道它们被复制了。
  • 它们的时间戳对应于我上次构建项目的时间,所以我知道它们是最新的。
  • 项目属性 > 调试 > 启动外部程序: 已自动设置为 C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.exe命令行参数 已自动设置为 /rootsuffix Exp
  • Visual Studio 日志(使用 /log 选项创建)有两个与我的扩展相关的条目:Successfully loaded extension...Extension is enabled...
  • 我的 DLL 出现在调试 Visual Studio 的 Modules 选项卡(所有加载的 DLL 的列表)上,而一些(不是全部)其他扩展 出现
  • 我的笔记本电脑和台式电脑上的 Visual Studio 2012 或 2010 都没有加载它。

我尝试过的:

  • 根据this suggestion,在.csproj 文件中将&lt;IncludeAssemblyInVSIXContainer&gt; 设置为true,但没有任何区别。
  • 不能将行 &lt;MefComponent&gt;|%CurrentProject%|&lt;/MefComponent&gt; 添加到 source.extension.vsixmanifest 文件中,因为它使用的格式 (2.0) 与以前版本的 VSIX 项目不同Visual Studio (1.0)。
  • This suggestion(将我的 .csproj 中的 IncludeAssemblyInVSIXContainer 和朋友设置为 true),但这并没有什么不同。而且我的断点仍然显示警告并且没有被命中。
  • 按照this suggestion,使用开始菜单中的重置 Visual Studio 2012 实验性实例 快捷方式重置 VS 实验性实例。没有什么不同。

如何至少确保我的 VSIX MEF 扩展已加载并正常工作?如果可能的话,我怎样才能通过断点工作并调试它?

【问题讨论】:

  • source.extension.vsixmanifest 行应如下所示(与您的不同之处在于包含% 字符):&lt;MefComponent&gt;|%CurrentProject%|&lt;/MefComponent&gt;
  • @280Z28 由于我的 source.extension.vsixmanifest 格式完全不同(它是 2.0 版,而不是 1.0 版),我认为 &lt;MefComponent&gt;|%CurrentProject%|&lt;/MefComponent&gt; 不应该在其中。
  • 下面的呢? &lt;Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%|" /&gt;
  • @280Z28 我寄予厚望,但是唉...没有改变任何事情(删除 objbin 文件夹后,清理并进行重建)。我在帖子中添加了完整的 vsixmanifest。

标签: c# debugging visual-studio-2012 vsix


【解决方案1】:

编辑:问题是您错误地将ContentTypeDefinition 导出为ClassificationTypeDefinition。您应该改用以下内容:

[Export] // <-- don't specify the type here
[Name(ContentType)]
[BaseDefinition("code")]
internal static ContentTypeDefinition MyLangSyntaxContentTypeDefinition = null;

这是我现在的两个猜测:

  1. 尝试从您的 vsixmanifest 中删除以下行。我假设您的项目中没有扩展 Package 的类,在这种情况下,Visual Studio 可能会由于以下资产行而拒绝加载您的包(您的扩展实际上并未提供此资产)。

    <Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
    
  2. 如果失败,请尝试将当前的 source.extension.vsixmanifest 替换为写入旧架构(1.0 版)的文件。我知道这种形式在 Visual Studio 2012 中仍然有效,因为我处理的所有大约 20 个扩展(超过 10 个公共版本)都使用旧架构。

【讨论】:

  • 不,很遗憾两者都不起作用。你能用我的full source复制它吗?
  • @Virtlink 发现了您的问题并编辑了我的答案以包含解决方案!
  • 我会被诅咒的!你说的对!我直接从Boo Syntax 代码someone on SO 中复制了它。但是我永远无法测试那个 Boo 代码,因为它缺少文件。我只是假设它是正确的。而且我从未发现我的代码和Microsoft's recommendation 之间的区别。它也适用于 VSIX 清单格式 2.0。干得好!
  • 您的建议for the VSIX 2.0 manifest、您的建议for the VSIX 1.0 manifest 以及您从清单中删除带有VsPackage 的行的建议都是正确的。不做任何这些事情都会导致扩展 not 被加载。
  • 上帝之母。对你们俩来说 +200,对这个问题感到沮丧几天,通过所有 Visual Studio 可扩展性 DLL 进行调试。只是把它扔在那里:我将我的包作为 MefComponent 添加到文件 ShellExtensionsVSIX\source.extension.vsixmanifest 并删除了一堆注册表项/缓存(12.0Exp 文件夹)和我自己的公司文件夹 + 干净的解决方案。它开始起作用了。不应该从零开始:-)。虽然我在路上学到了很多东西。
【解决方案2】:

280Z28 solved the problem!为了完整起见,这是完整的经过试验和测试的代码,它将创建一个超级简单的 VSIX Visual Studio MEF 扩展,为 .mylang 文件 blue 中的所有文本着色(或任何当前关键字颜色)。

如何创建简单的着色 MEF VSIX 扩展

  1. 确保已安装 Visual Studio SDK。 (VS2010 SP1 SDK, VS2012 SDK)
  2. 创建一个新的 VSIX 项目
    (从 Installed 下的模板 → 模板Visual C#可扩展性 em>.)
  3. 在 VSIX 清单编辑器的 作者 字段中输入内容,然后保存并关闭它。
  4. 添加对以下库的引用,
    VS2010 版本 10.0.0.0,或 VS2012 版本 11.0.0.0:

    • Microsoft.VisualStudio.CoreUtility.dll
    • Microsoft.VisualStudio.Language.StandardClassification.dll
    • Microsoft.VisualStudio.Text.Data.dll
    • Microsoft.VisualStudio.Text.Logic.dll
    • Microsoft.VisualStudio.Text.UI.dll
    • Microsoft.VisualStudio.Text.UI.Wpf.dll
  5. 添加对以下库的引用:

    • System.ComponentModel.Composition.dll 4.0.0.0版
  6. 创建并添加一个新的代码文件MyLang.cs,并在其中复制并粘贴the code below

  7. source.extension.vsixmanifest 编辑为 XML。

    • 对于 Visual Studio 2010,在结束标记 &lt;/Vsix&gt; 之前添加以下 XML,然后保存:

      <Content>
          <MefComponent>|%CurrentProject%|</MefComponent>
      </Content>
      

      (如果已经有一个空的&lt;Content/&gt;,删除它。)

    • 对于 Visual Stuio 2012,在结束标记 &lt;/PackageManifest&gt; 之前添加以下 XML,然后保存:

      <Assets>
          <Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%|" />
      </Assets>
      

      (如果已经有一个空的&lt;Assets/&gt;,请将其删除。)

  8. 仅适用于 Visual Studio 2010

    • 卸载 VSIX 项目(右键单击项目 → 卸载项目)。

    • 编辑.csproj项目文件(右击项目→编辑MyProject.csproj)。

    • &lt;IncludeAssemblyInVSIXContainer&gt;的值更改为true

    • 保存并关闭文件。

    • 重新加载 VSIX 项目(右键单击项目 → 重新加载项目)。

  9. 现在构建并运行它。当您加载 .mylang 文件时,所有文本都应为蓝色(或任何默认关键字颜色)。


MyLang.cs

using Microsoft.VisualStudio.Language.StandardClassification;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Utilities;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;

namespace VSIXProject1
{
    internal static class MyLangLanguage
    {
        public const string ContentType = "mylang";

        public const string FileExtension = ".mylang";

        [Export]
        [Name(ContentType)]
        [BaseDefinition("code")]
        internal static ContentTypeDefinition MyLangSyntaxContentTypeDefinition = null;

        [Export]
        [FileExtension(FileExtension)]
        [ContentType(ContentType)]
        internal static FileExtensionToContentTypeDefinition MyLangSyntaxFileExtensionDefinition = null;
    }

    [Export(typeof(IClassifierProvider))]
    [ContentType(MyLangLanguage.ContentType)]
    [Name("MyLangSyntaxProvider")]
    internal sealed class MyLangSyntaxProvider : IClassifierProvider
    {
        [Import]
        internal IClassificationTypeRegistryService ClassificationRegistry = null;

        public IClassifier GetClassifier(ITextBuffer buffer)
        {
            return buffer.Properties.GetOrCreateSingletonProperty(() => new MyLangSyntax(ClassificationRegistry, buffer));
        }
    }

    internal sealed class MyLangSyntax : IClassifier
    {
        private ITextBuffer buffer;
        private IClassificationType identifierType;
        private IClassificationType keywordType;

        public event EventHandler<ClassificationChangedEventArgs> ClassificationChanged;

        internal MyLangSyntax(IClassificationTypeRegistryService registry, ITextBuffer buffer)
        {
            this.identifierType = registry.GetClassificationType(PredefinedClassificationTypeNames.Identifier);
            this.keywordType = registry.GetClassificationType(PredefinedClassificationTypeNames.Keyword);
            this.buffer = buffer;
            this.buffer.Changed += OnBufferChanged;
        }

        public IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan snapshotSpan)
        {
            var classifications = new List<ClassificationSpan>();

            string text = snapshotSpan.GetText();
            var span = new SnapshotSpan(snapshotSpan.Snapshot, snapshotSpan.Start.Position, text.Length);
            classifications.Add(new ClassificationSpan(span, keywordType));

            return classifications;
        }

        private void OnBufferChanged(object sender, TextContentChangedEventArgs e)
        {
            foreach (var change in e.Changes)
                ClassificationChanged(this, new ClassificationChangedEventArgs(new SnapshotSpan(e.After, change.NewSpan)));
        }
    }
}

【讨论】:

  • 您没有从分类器示例开始的任何原因?它会为您设置大部分内容。
  • @JasonMalinowski 你是说Editor Classifier 项目?在您发表评论之前,我不知道它创建了一个 VSIX 项目。而且它不包括internal static ContentTypeDefinition MyDefinition 行,所以我仍然可以在我这样做的时候搞砸[Export]
  • 是的,它会创建一个 VSIX 项目并为您执行步骤 4 到 8。我实际上鄙视空的 VSIX 项目模板,因为它需要太多微妙的知识来了解 VSSDK 构建的东西是如何工作的。
  • 实际上,我更喜欢您的最小实现,而不是有些臃肿的编辑器分类器(在 VS 2015 中,它现在位于空 VSIX 项目中的“添加新项目”下)。并且您的 MyLang.cs 在 2015 年仍然可以正常工作,而无需更改任何一行代码。谢谢。
【解决方案3】:

在 .csproj 文件中将 &lt;IncludeAssemblyInVSIXContainer&gt; 设置为 true,根据 这个建议。

我遇到了完全相同的问题,这解决了它。进行全面重建。

【讨论】:

  • 我怎么知道它是否有效?我的断点不起作用,我的异常没有被抛出,我的文本没有被着色。我不认为它起作用了。它适用于您的安装吗?只需创建一个新的 VSIX 项目,添加上述引用并创建一个包含 my full source code 的 .cs 文件。
  • 好吧,那不是完全相同的问题 :) 你试过this 吗?
猜你喜欢
  • 2014-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多