Erstellen einer einfachen Erweiterung

In Create your first extension, you learn how to use the VisualStudio.Extensibility project template to create an extension project, and learned how to build it and debug it in the experimental instance of Visual Studio.

In diesem Lernprogramm erfahren Sie, wie Sie eine Erweiterung mit einem einfachen Befehl erstellen, der im Visual Studio-Editor etwas ausführt. In diesem Fall wird eine neu generierte GUID eingefügt. Außerdem erfahren Sie, wie Sie Visual Studio mitteilen, für welche Dateitypen die GUID-Erweiterung aktiviert ist, und wie der neue Befehl als Symbolleiste oder Menüelement angezeigt wird.

Das vollständige Beispiel für dieses Lernprogramm finden Sie hier.

Das Lernprogramm enthält die folgenden Schritte:

Konfigurieren des Befehls

In diesem Schritt erfahren Sie mehr über Optionen zum Konfigurieren und Platzieren des Befehls. Der Zweck des Hostens des Befehls besteht darin, ihn dem Benutzer auf irgendeine Weise verfügbar zu machen, z. B. das Hinzufügen eines Menüelements oder einer Befehlsleistenschaltfläche.

Die Projektvorlage oder das Beispiel, das Sie im Lernprogramm zum Erstellen ihrer ersten Erweiterung erstellt haben, besteht aus einer einzelnen C#-Datei, die bereits eine Command Klasse enthält. Sie können dies an Ort und Stelle aktualisieren.

  1. Benennen Sie die Command1.cs Datei in InsertGuidCommand.cs, benennen Sie die Klasse InsertGuidCommandum, aktualisieren Sie die CommandConfiguration Eigenschaft.

    public override CommandConfiguration CommandConfiguration => new("%InsertGuidCommand.DisplayName%")
    {
        Placements = new[] { CommandPlacement.KnownPlacements.ExtensionsMenu },
    };
    

    Placements Gibt an, wo der Befehl in der IDE angezeigt werden soll. In diesem Fall wird der Befehl im Menü "Erweiterungen" platziert, einem der Menüs der obersten Ebene in Visual Studio.

    Das Argument für den CommandConfiguration Konstruktor ist der Anzeigename des Befehls, bei dem es sich um den Menütext handelt. Der Anzeigename wird durch % Zeichen eingeschlossen, da er auf eine Zeichenfolgenressource verweist, um .vsextension/string-resources.json die Lokalisierung zu unterstützen.

  2. Aktualisieren .vsextension/string-resources.json mit dem Anzeigenamen von InsertGuidCommand.

    {
      "InsertGuidCommand.DisplayName": "Insert new guid"
    }
    
  3. Hinzufügen der Icon-Eigenschaft.

    public override CommandConfiguration CommandConfiguration => new("%InsertGuidCommand.DisplayName%")
    {
        Placements = new[] { CommandPlacement.KnownPlacements.ExtensionsMenu },
        Icon = new(ImageMoniker.KnownValues.OfficeWebExtension, IconSettings.IconAndText),
    };
    

    Sie können ein bekanntes integriertes Symbol in diesem Fall OfficeWebExtensionangeben oder Bilder für das Symbol hochladen, wie in Visual Studio-Befehlen beschrieben. Das zweite Argument ist eine Aufzählung, die bestimmt, wie der Befehl in Symbolleisten angezeigt werden soll (zusätzlich zur Position in einem Menü). Die Option IconSettings.IconAndText bedeutet, dass das Symbol und der Anzeigename nebeneinander angezeigt werden.

  4. Fügen Sie die VisibleWhen Eigenschaft hinzu, die die Bedingungen angibt, die für das Element gelten müssen, damit das Element dem Benutzer angezeigt wird.

    public override CommandConfiguration CommandConfiguration => new("%InsertGuidCommand.DisplayName%")
    {
        Placements = new[] { CommandPlacement.KnownPlacements.ExtensionsMenu },
        Icon = new(ImageMoniker.KnownValues.OfficeWebExtension, IconSettings.IconAndText),
        VisibleWhen = ActivationConstraint.ClientContext(ClientContextKey.Shell.ActiveEditorContentType, ".+"),
    };
    

Weitere Informationen finden Sie unter Verwendung regelbasierter Aktivierungseinschränkungen .

Erstellen der Ausführungsmethode

In diesem Schritt implementieren Sie die Methode des ExecuteCommandAsync Befehls, die definiert, was passiert, wenn der Benutzer das Menüelement auswählt, oder das Element in der Symbolleiste für Den Befehl drückt.

Kopieren Sie den folgenden Code, um die Methode zu implementieren.

public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
    {
        Requires.NotNull(context, nameof(context));
        var newGuidString = Guid.NewGuid().ToString("N", CultureInfo.CurrentCulture);

        using var textView = await context.GetActiveTextViewAsync(cancellationToken);
        if (textView is null)
        {
            this.logger.TraceInformation("There was no active text view when command is executed.");
            return;
        }

        await this.Extensibility.Editor().EditAsync(
            batch =>
            {
                textView.Document.AsEditable(batch).Replace(textView.Selection.Extent, newGuidString);
            },
            cancellationToken);
    }

In der ersten Zeile werden die Argumente überprüft. Anschließend erstellen wir eine neue Guid , die später verwendet werden soll.

Anschließend erstellen wir ein ITextViewSnapshot (das textView Objekt hier) durch Aufrufen der asynchronen Methode GetActiveTextViewAsync. Ein Abbruchtoken wird übergeben, um die Möglichkeit zum Abbrechen der asynchronen Anforderung zu erhalten, aber dieser Teil wird in diesem Beispiel nicht veranschaulicht. Wenn wir keine Textansicht erfolgreich erhalten, schreiben wir in das Protokoll und beenden, ohne etwas anderes zu tun.

Jetzt können wir die asynchrone Methode aufrufen, die eine Bearbeitungsanforderung an den Editor von Visual Studio sendet. Die gewünschte Methode lautet EditAsync. Dies ist ein Element der EditorExtensibility Klasse, das die Interaktion mit dem ausgeführten Visual Studio-Editor in der IDE ermöglicht. Der Command Typ, von dem Ihre eigene InsertGuidCommand Klasse erbt, verfügt über ein ElementExtensibility, das Zugriff auf das EditorExtensibility Objekt bietet, sodass wir mit einem Aufruf this.Extensibility.Editor()zur EditorExtensibility Klasse gelangen können.

Die EditAsync Methode verwendet einen Action<IEditBatch> Parameter. Dieser Parameter wird aufgerufen editorSource,

Der Aufruf, um einen Lambda-Ausdruck zu EditAsync verwenden. Um dies ein wenig aufzuschlüsseln, könnten Sie diesen Anruf auch wie folgt schreiben:

await this.Extensibility.Editor().EditAsync(
    batch =>
    {
        var editor = textView.Document.AsEditable(batch);
        // specify the desired changes here:
        editor.Replace(textView.Selection.Extent, newGuidString);
    },
    cancellationToken);

Sie können sich diesen Aufruf als Angabe des Codes vorstellen, den Sie im Visual Studio-Editorprozess ausführen möchten. Der Lambda-Ausdruck gibt an, was im Editor geändert werden soll. Dies batch bedeutet IEditBatch, dass der hier definierte Lambda-Ausdruck einen kleinen Satz von Änderungen vornimmt, die als Einheit durchgeführt werden sollten, anstatt von anderen Bearbeitungen durch den Benutzer oder sprachdienst unterbrochen zu werden. Wenn der Code zu lang ausgeführt wird, kann dies zu einer Nichtzuverzögerung führen, daher ist es wichtig, Änderungen innerhalb dieses Lambda-Ausdrucks begrenzt zu halten und alles zu verstehen, was zu Verzögerungen führen könnte.

Mithilfe der AsEditable Methode für das Dokument erhalten Sie ein temporäres Editorobjekt, mit dem Sie die gewünschten Änderungen angeben können. Stellen Sie sich alles im Lambda-Ausdruck als Anforderung für die Ausführung von Visual Studio vor, anstatt als tatsächlich auszuführen, da, wie in der Erweiterbarkeit des Visual Studio-Editors beschrieben, ein bestimmtes Protokoll für die Behandlung dieser asynchronen Bearbeitungsanforderungen von Erweiterungen vorhanden ist, und es gibt die Möglichkeit, dass die Änderungen nicht akzeptiert werden, z. B. wenn der Benutzer Gleichzeitig Änderungen vornimmt, die einen Konflikt verursachen.

Das EditAsync Muster kann verwendet werden, um Text im Allgemeinen zu ändern, indem Sie Ihre Änderungen nach dem Kommentar "Ihre gewünschten Änderungen hier angeben" angeben.