调试时VS2012的VSIX扩展未运行

时间:2013-05-07 14:46:19

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

我在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文件,因此我知道它们已被复制。
  • 他们的时间戳对应于我上次构建项目的时间,因此我知道它们是最新的。
  • 项目属性&gt;调试&gt;启动外部程序:已自动设置为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 文件中的<IncludeAssemblyInVSIXContainer>设置为true,但它没有任何区别。
  • 无法将行<MefComponent>|%CurrentProject%|</MefComponent>添加到 source.extension.vsixmanifest 文件,因为它使用的格式(2.0)与VSIX项目不同以前版本的Visual Studio(1.0)。
  • This suggestion(将 .csproj 中的IncludeAssemblyInVSIXContainer和朋友设置为true),但这没有任何区别。我的断点仍然显示警告而没有被击中。
  • 根据this suggestion,使用“开始”菜单中的重置Visual Studio 2012实验实例快捷方式重置VS Experimental实例。它并没有什么区别。

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

3 个答案:

答案 0 :(得分:7)

修改:问题是您错误地将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个扩展(使用&gt; 10个公共版本)都使用旧模式。

答案 1 :(得分:4)

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

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

  1. 确保安装了Visual Studio SDK。 (VS2010 SP1 SDKVS2012 SDK
  2. 创建新的VSIX项目
    (从已安装模板下的模板→ Visual C#可扩展性< / em>的。)
  3. 在VSIX清单编辑器的 Author 字段中输入内容,然后保存并关闭它。
  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,在结束标记</Vsix>之前添加以下XML,并保存:

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

      (如果已经有空<Content/>,请将其删除。)

    • 对于Visual Stuio 2012,在结束标记</PackageManifest>之前添加以下XML,并保存:

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

      (如果已经有空<Assets/>,请将其删除。)

  8. 仅适用于Visual Studio 2010

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

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

    • <IncludeAssemblyInVSIXContainer>的值更改为true

    • 保存并关闭文件。

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

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


  10. <强> 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)));
            }
        }
    }
    

答案 2 :(得分:0)

  

在.csproj文件中将<IncludeAssemblyInVSIXContainer>设置为true   这个建议。

我有完全相同的问题,这解决了它。做一次完整的重建。