我在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和两个资产的依赖。
<?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 problem和this 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
。/log
选项创建)有两个与我的扩展程序相关的条目:Successfully loaded extension...
和Extension is enabled...
。我尝试了什么:
<IncludeAssemblyInVSIXContainer>
设置为true
,但它没有任何区别。<MefComponent>|%CurrentProject%|</MefComponent>
添加到 source.extension.vsixmanifest 文件,因为它使用的格式(2.0)与VSIX项目不同以前版本的Visual Studio(1.0)。IncludeAssemblyInVSIXContainer
和朋友设置为true
),但这没有任何区别。我的断点仍然显示警告而没有被击中。我怎样才能确保我的VSIX MEF扩展加载并运行?如果可能的话,我如何通过断点工作并调试它?
答案 0 :(得分:7)
修改:问题是您错误地将ContentTypeDefinition
导出为ClassificationTypeDefinition
。您应该使用以下代码:
[Export] // <-- don't specify the type here
[Name(ContentType)]
[BaseDefinition("code")]
internal static ContentTypeDefinition MyLangSyntaxContentTypeDefinition = null;
这是我现在的两个猜测:
尝试从您的vsixmanifest中删除以下行。我假设您的项目中没有扩展Package
的类,在这种情况下,由于以下资产行,Visual Studio可能拒绝加载您的包(您的扩展实际上不提供此资产)。
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
如果失败,请尝试将当前的source.extension.vsixmanifest替换为写入旧架构(版本1.0)的源码。我知道这个表单在Visual Studio 2012中仍然有效,因为我所使用的所有~20个扩展(使用&gt; 10个公共版本)都使用旧模式。
答案 1 :(得分:4)
280Z28 solved the problem!为了完整性,这是经过充分尝试和测试的代码,它将创建一个超级简单的VSIX Visual Studio MEF扩展,为.mylang
文件 blue 中的所有文本着色(或者当前关键字颜色为)。
添加对以下库的引用,对于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
,并在其中复制并粘贴the code below。
将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/>
,请将其删除。)
仅适用于Visual Studio 2010 :
卸载VSIX项目(右键单击项目→卸载项目)。
编辑.csproj
项目文件(右键单击项目→编辑MyProject.csproj )。
将<IncludeAssemblyInVSIXContainer>
的值更改为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<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 这个建议。
我有完全相同的问题,这解决了它。做一次完整的重建。