10

Visual Studio 2012 で新しい VSIX 拡張プロジェクトを作成し、.mylangファイル内のすべてのテキストを単純に強調表示する MEF 分類子を (テストとして) 作成しました。私の.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ファイルの関連部分です。Web で見つけた提案や同様のファイルに基づいて、MPF と 2 つのアセットへの依存関係を追加しました。

<?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 の実験的なインスタンスが起動し、[拡張機能と更新プログラム]ウィンドウに拡張機能がアクティブであることが示されます。ただし、.mylang ファイルをロードまたは作成すると、何も実行されません。拡張機能から (テストとして) スローした例外はスローされません。ブレークポイントがヒットすることはなく、次の警告とともに感嘆符が表示されます。

ブレークポイントは現在ヒットしません。このドキュメントのシンボルは読み込まれていません。

私の拡張機能がまったくロードされていないように感じます。私の問題はこの問題この問題に似ていますが、新しい VSIX マニフェスト形式を使用する Visual Studio 2012 を使用しています。

私が知っていること:

  • DLL と VSIX ファイルが%localappdata%\Microsoft\VisualStudio\11.0Exp\Extensions\MyLang\VSIXProject1\1.0フォルダーにあるので、それらがコピーされていることがわかります。
  • それらのタイムスタンプは、私が最後にプロジェクトをビルドした時刻に対応しているため、それらが最新であることがわかります。
  • プロジェクト プロパティ > デバッグ > 外部プログラムの開始:は既に自動的に に設定されてC:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.exeおり、コマンド ライン引数は自動的に に設定されてい/rootsuffix Expます。
  • Visual Studio ログ (/logオプションで作成) には、私の拡張機能に関連する 2 つのエントリがあります:Successfully loaded extension...Extension is enabled....
  • 私の DLL は、Visual Studio のデバッグの [モジュール] タブ (読み込まれたすべての DLL のリスト) に表示されませんが、一部の (すべてではない) 他の拡張機能表示されます。
  • ラップトップとデスクトップ PC の両方で、Visual Studio 2012 または 2010 に読み込まれません。

私が試したこと:

  • この提案に従って、.csprojファイルに設定<IncludeAssemblyInVSIXContainer>しますが、違いはありませんでした。true
  • 以前のバージョンの Visual Studio (1.0) の VSIX プロジェクトとは異なる形式 (2.0) を使用しているため、source.extension.vsixmanifestファイルに行を追加できません。<MefComponent>|%CurrentProject%|</MefComponent>
  • この提案( .csprojの設定IncludeAssemblyInVSIXContainerと友達を) にしますが、違いはありません。そして、私のブレークポイントはまだ警告を表示しており、ヒットしていません。true
  • この提案に従って、[スタート] メニューの [ Visual Studio 2012 実験的インスタンスをリセット] ショートカットを使用して、VS 実験的インスタンスをリセットします。違いはありませんでした。

少なくとも、VSIX MEF 拡張機能が読み込まれて動作していることを確認するにはどうすればよいですか? 可能であれば、ブレークポイントで動作させてデバッグするにはどうすればよいですか?

4

3 に答える 3

7

編集:問題は、不適切にエクスポートContentTypeDefinitionしたことClassificationTypeDefinitionです. 代わりに次を使用する必要があります。

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

現時点での私の推測は次の 2 つです。

  1. vsixmanifest から次の行を削除してみてください。プロジェクトに を拡張するクラスがないと仮定します。Packageその場合、Visual Studio は次の Asset 行が原因でパッケージの読み込みを拒否している可能性があります (拡張機能は実際にはこのアセットを提供しません)。

    <Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
    
  2. それが失敗した場合は、現在の source.extension.vsixmanifest を古いスキーマ (バージョン 1.0) に書き込まれたものに置き換えてみてください。私が取り組んでいる ~20 の拡張機能 (10 を超えるパブリック リリース) はすべて古いスキーマを使用しているため、このフォームは Visual Studio 2012 でも機能します。

于 2013-05-10T15:22:11.893 に答える
4

280Z28で問題解決.mylang完全を期すために、これは、ファイル内のすべてのテキストを(または現在のキーワードの色が何であれ) に色付けする非常に単純な VSIX Visual Studio MEF 拡張機能を作成する、十分に試行錯誤された完全なコードです。

シンプルなカラーリング MEF VSIX 拡張機能の作成方法

  1. Visual Studio SDK がインストールされていることを確認してください。( VS2010 SP1 SDKVS2012 SDK )
  2. 新しい VSIX プロジェクトを作成します
    ( InstalledTemplatesVisual C#Extensibilityのテンプレートから)。
  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をコピーしてそのファイルに貼り付けます。

  7. source.extension.vsixmanifestXML として編集します。

    • Visual Studio 2010 の場合、終了タグの直前に次の XML を追加して</Vsix>保存します。

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

      (すでに空の がある場合は<Content/>、それを削除します。)

    • Visual Stuio 2012 の場合は、終了タグの直前に次の XML を追加して</PackageManifest>保存します。

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

      (すでに空の がある場合は<Assets/>、それを削除します。)

  8. Visual Studio 2010 のみ:

    • VSIX プロジェクトをアンロードします (プロジェクトを右クリック → プロジェクトのアンロード)。

    • プロジェクト ファイルを編集し.csprojます (プロジェクトを右クリック → Edit MyProject.csproj )。

    • の値を<IncludeAssemblyInVSIXContainer>に変更します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)));
        }
    }
}
于 2013-05-11T00:47:35.177 に答える