VS2012的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 { }
这是完整的代码 。
这些是我的source.extension.vsixmanifest
文件中的相关部分。 根据我在网上找到的建议和类似文件,我添加了对MPF和两个资产的依赖。
我还尝试了1.0版本清单:
|%CurrentProject%|
当我运行它时,它启动Visual Studio 2012的实验性实例,“ 扩展和更新”窗口显示我的扩展名处于活动状态。 但是,当我加载或创建.mylang文件时,它不会执行任何操作。 我从我的扩展中抛出(作为测试)的任何exception都不会被抛出。 断点永远不会被击中,并获得带有以下警告的感叹号:
断点当前不会被击中。 没有为此文档加载任何符号。
感觉好像我的扩展从未真正加载过。 我的问题类似于这个问题和这个问题 ,但我使用的是使用新的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的“ 模块”选项卡(所有加载的DLL的列表)上,而某些(并非所有)其他扩展名确实出现。
- 它不会在我的笔记本电脑和台式机上加载到Visual Studio 2012或2010中。
我尝试过的:
- 根据此建议 ,在.csproj文件中将
设置为
true
,但它没有任何区别。 - 我无法将行
|%CurrentProject%|
到|%CurrentProject%|
文件,因为它使用的格式(2.0)与以前版本的Visual Studio(1.0)的VSIX项目不同。 - 这个建议 (将我的.csproj中的
IncludeAssemblyInVSIXContainer
和朋友设置为true
)但它没有什么区别。 我的断点仍然显示警告而没有被击中。 - 根据此建议 ,使用“开始”菜单中的“ 重置Visual Studio 2012实验实例”快捷方式重置VS实验实例。 它没有任何区别。
我怎么能够确定我的VSIX MEF扩展已加载并且有效? 如果可能的话,我如何通过断点工作并调试它?
编辑:问题是您已将ContentTypeDefinition
不正确地导出为ClassificationTypeDefinition
。 您应该使用以下代码:
[Export] // <-- don't specify the type here [Name(ContentType)] [BaseDefinition("code")] internal static ContentTypeDefinition MyLangSyntaxContentTypeDefinition = null;
这是我现在的两个猜测:
-
尝试从您的vsixmanifest中删除以下行。 我假设您的项目中没有扩展
Package
,在这种情况下,由于以下资产行,Visual Studio可能拒绝加载您的包(您的扩展实际上并不提供此资产)。 -
如果失败,请尝试将当前的source.extension.vsixmanifest替换为写入旧架构(版本1.0)的源代码。 我知道这个表单在Visual Studio 2012中仍然有效,因为我工作的所有~20个扩展(具有> 10个公共版本)都使用旧模式。
280Z28解决了这个问题 ! 为了完整.mylang
,这是经过充分尝试和测试的代码,它将创建一个超级简单的VSIX Visual Studio MEF扩展, .mylang
文件中的所有文本(或当前关键字颜色)都着色。
如何创建一个简单的着色MEF VSIX扩展
- 确保安装了Visual Studio SDK。 ( VS2010 SP1 SDK , VS2012 SDK )
- 创建一个新的VSIX项目
(从已安装 → 模板 → Visual C# → 可扩展性下的模板中 。) - 在VSIX清单编辑器的“ 作者”字段中输入内容,然后保存并关闭它。
-
添加对以下库的引用,
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
-
-
添加对以下库的引用:
-
System.ComponentModel.Composition.dll
版本4.0.0.0
-
-
创建并添加新的代码文件
MyLang.cs
,并将下面的代码复制并粘贴到其中。 -
将
source.extension.vsixmanifest
编辑为XML。-
对于Visual Studio 2010,在结束标记
之前添加以下XML,并保存:
|%CurrentProject%| (如果已经有空
,请将其删除。) -
对于Visual Stuio 2012,在结束标记
之前添加以下XML,并保存:
(如果已有空
,请将其删除。)
-
-
仅适用于Visual Studio 2010 :
-
卸载VSIX项目(右键单击项目→ 卸载项目 )。
-
编辑
.csproj
项目文件(右键单击项目→ 编辑MyProject.csproj )。 -
将
的值更改为true
。 -
保存并关闭文件。
-
重新加载VSIX项目(右键单击项目→ 重新加载项目 )。
-
-
现在构建并运行它。 加载
.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 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 GetClassificationSpans(SnapshotSpan snapshotSpan) { var classifications = new List (); 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))); } } }
根据此建议,在.csproj文件中将
设置为true。
我有完全相同的问题,这解决了它。 做一个完整的重建。