Visual Studio 2013

Erweitern von Visual Studio 2013 durch Erweiterungen

Doug Erickson
Susan Norwood

Eine der besten Funktionen in den professionelleren Versionen von Visual Studio ist nun kostenlos für alle Benutzer über die Visual Studio Community 2013-IDE verfügbar: die Möglichkeit, Erweiterungen aus der Visual Studio Gallery verwenden zu können (Sie finden die Erweiterungen unter bit.ly/115mBzm). Was also sind Erweiterungen? Dabei handelt es sich um Plug-Ins, mit denen Sie Visual Studio Community 2013 (kann unter bit.ly/1tH2uyc heruntergeladen werden) und Funktionen von Visual Studio so erweitern können, dass neue Aufgaben ausgeführt bzw. neue Funktionen und Umgestaltungscode hinzugefügt werden – oder sogar Unterstützung für neue Sprachen verfügbar wird.

Die Microsoft-Entwicklercommunity stellt eine breite Palette von Erweiterungen in der Visual Studio Gallery zur Verfügung. Sie werden überrascht sein, welche Arten von Erweiterungen verfügbar sind, wenn Sie sich die Gallery ansehen. Einige dieser Erweiterungen, z. B. die Erweiterung Productivity Power Tools 2013 (Download unter bit.ly/1xE3EAT), werden Sie nicht mehr missen wollen. Sie können diese Erweiterungen aus dem Web installieren, oder Sie können in Visual Studio mithilfe des Fensters „Erweiterungen und Updates“ im Menü „Tools“ nach Onlineerweiterungen suchen. Suchen Sie in der Kategorie „Online“, wenn Sie an beliebten Tools wie etwa Visual Assist und ReSharper interessiert sind. Noch mehr Erweiterungen finden Sie in der Code Gallery (bit.ly/11nzi9Q).

Selbst die besten Tools eignen sich ggf. nicht perfekt für bestimmte Aufgaben, die Sie ausführen oder in der IDE automatisieren möchten. Möglicherweise verfügen Sie über eigene, persönliche Skripts, die Sie angepasst und optimiert haben, um sich die Arbeit zu vereinfachen. Vielleicht verwenden Sie ein Skript, das ein Buildverzeichnis auf einen erfolgreichen Build überprüft, eine Transformation für XML-Dateien ausführt oder alle Hinterlassenschaften eines komplexen Buildvorgangs bereinigt. Wie möchten Sie Ihr Tool in Visual Studio als Teil der IDE oder als Teil Ihres Buildvorgangs ausführen? Mithilfe von Visual Studio 2013 Community und mit dem Visual Studio 2013 SDK ist dies nun möglich.

Als ersten Schritt können Sie das Visual Studio SDK herunterladen. Es stellt alle Bibliotheken, Tools und Projektvorlagen zum Erstellen einer Vielzahl verschiedener Erweiterungen zur Verfügung. Installieren Sie es einfach – damit sind schon alle Vorbereitungen getroffen.

Einrichten von Tools für die Ausführung in Visual Studio

Nachdem das SDK installiert wurde, ist es recht einfach, Ihr Tool oder ein ausführbares Skript über ein Visual Studio-Menü auszuführen. Der allgegenwärtige Editor („Notepad.exe“) dient in diesem Artikel als Beispiel. Sie können jedoch auch jede andere ausführbare Datei verwenden oder Ihren eigenen Code in den Befehlshandler integrieren.

Eine Basiserweiterung ist eine Visual Studio-Paketbinärdatei. Sie finden die Visual Studio-Paketvorlage im Dialogfeld „Neues Projekt“ unter „Visual Basic | Erweiterungen, C# | Erweiterungen“ oder unter „Andere Projekttypen | Erweiterungen“.

In diesem Artikel wird gezeigt, wie eine einfache Erweiterung erstellt wird, die den Editor startet. Wir verwenden eine Vorlage unter „C#/Erweiterbarkeit“, um ein C# Visual Studio-Paketprojekt zu erstellen. Dieses wird im Verzeichnis „D:\Code“ unter dem Namen „StartNotepad“ gespeichert. Diese Erweiterung startet schließlich den Editor aus einem Menüelement der Visual Studio-IDE.

Sobald Sie auf die Vorlage doppelklicken, startet Visual Studio einen Assistenten, der Sie bei der Konfiguration der Erweiterung unterstützt. Übernehmen Sie zunächst einmal einfach die Standardeinstellungen auf den ersten beiden Dialogfeldseiten.

Führen Sie dann die folgenden Schritte aus:

  1. Wählen Sie auf der Seite „Optionen für VSPackage auswählen“ die Option „Menübefehl“ aus.
  2. Legen Sie auf der Seite „Befehlsoptionen“ den Name des Befehls auf „Start Notepad“ und die Befehls-ID auf „cmdidStartNotepad“ fest.
  3. Deaktivieren Sie auf der Seite „Testoptionen“ die beiden Kontrollkästchen.
  4. Klicken Sie auf „Fertig stellen“.

An diesem Punkt können Sie das Paketprojekt erstellen und ausführen. Wenn das Projekt geöffnet wird, starten Sie das Debuggen (drücken Sie die Taste F5, oder verwenden Sie den Befehl „Start“ auf der Symbolleiste). Eine neue Instanz von Visual Studio Community 2013 wird gestartet. Nach dem Start wird die IDE angezeigt. Standardmäßig enthält die Titelleiste die Angabe „Startseite – Microsoft Visual Studio – Experimentelle Instanz“ (siehe Abbildung 1). Dies ist Ihre Testinstanz von Visual Studio. Sie wird separat von Ihrer Arbeitsinstanz von Visual Studio ausgeführt, damit Sie unbesorgt sein können, dass Ihre eigene Entwicklungsumgebung kontaminiert wird, wenn ein Fehler auftritt.

Die experimentelle Visual Studio-Instanz
Abbildung 1 – Die experimentelle Visual Studio-Instanz

Die „experimentelle Instanz“ drückt einfach nur auf originelle Weise aus, dass Sie eine Sandkasteninstanz von Visual Studio zum Testen Ihrer Erweiterung erstellt haben. Diese weist alle Funktionen von Visual Studio Community 2013 auf, gefährdet jedoch nicht Ihre Arbeit in der ursprünglichen Visual Studio-Instanz. Für ein so einfaches Beispiel kann dies als zu viel des Guten erscheinen. Wenn Sie jedoch ein vollständiges Entwurfsframework oder eine komplexe, unabhängig Sammlung von Buildtools erstellen, möchten Sie bestimmt nicht Ihren Code riskieren, indem Sie ihn in der gleichen Instanz ausführen, in der die Entwicklung stattfindet.

Öffnen Sie im Menü „Tools“ der experimentellen Instanz das Fenster „Erweiterungen und Updates“. Die Erweiterung „StartNotepad“ sollte angezeigt werden (siehe Abbildung 2). (Wenn Sie „Erweiterungen und Updates“ in Ihrer Arbeitsinstanz von Visual Studio öffnen, wird „StartNotePad“ nicht angezeigt.)

„Erweiterungen und Updates“ mit „StartNotepad“
Abbildung 2 – „Erweiterungen und Updates“ mit „StartNotepad“

„Start Notepad“ wird auch im Menü „Tools“ angezeigt (siehe Abbildung 3).

Bestätigung des neuen Menüelements für „StartNotepad“ unter „Tools“
Abbildung 3 – Bestätigung des neuen Menüelements für „StartNotepad“ unter „Tools“

Navigieren Sie nun in der experimentellen Instanz zum Menü „Tools“. Der Befehl „Start Notepad“ sollte angezeigt werden. Zu diesem Zeitpunkt wird nur ein Meldungsfeld mit dem Text „StartNotepad – Inside MSIT.StartNotepad.StartNotepadPackage.MenuItemCallback()“ angezeigt. Sie erfahren im nächsten Abschnitt, wie der Editor über diesen Befehl tatsächlich gestartet wird.

Einrichten des Menübefehls

Beenden Sie das Debuggen, und wechseln Sie zurück in Ihre Arbeitsinstanz von Visual Studio. Öffnen Sie die Datei „StartNotepadPackage.cs“, die die abgeleitete Paketklasse enthält. Diese ist der Ausgangspunkt für alle VSPackage-Erweiterungen. Die Methode „Initialize“ dieser Klasse richtet den Befehl ein:

// Add our command handlers for menu (commands must exist in the .vsct file)
OleMenuCommandService mcs =
  GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
if ( null != mcs )
{
  // Create the command for the menu item.
  CommandID menuCommandID = new CommandID(GuidList.guidStartNotepadCmdSet,
    (int)PkgCmdIDList.cmdidStartNotepad);
  MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID );
  mcs.AddCommand( menuItem );
}

Machen Sie sich im Moment noch keine Gedanken über die Details dieses Codes. Sie sollten sich nur merken, dass der Menübefehl auf diese Weise instanziiert wird. Die Menüs und die weitere Benutzeroberfläche für VSPackage-Erweiterungen werden (wie der Codekommentar besagt) in der VSCT-Datei definiert.

Der Befehlshandler trägt den Namen „MenuItemCallback“ (in der gleichen Klasse „StartNotepadPackage“). Löschen Sie die vorhandene Methode, und fügen Sie dann Folgendes hinzu:

private void MenuItemCallback(object sender, EventArgs e)
{
  Process proc = new Process();
  proc.StartInfo.FileName = "notepad.exe";
  proc.Start();
}

Probieren Sie die Implementierung nun aus. Wenn Sie mit dem Debuggen des Projekts beginnen und auf „Tools | Start Notepad“ klicken, sollte eine Instanz des Editors angezeigt werden. Tatsächlich wird bei jedem Klicken auf „Start Notepad“ eine neue Instanz angezeigt. 

Sie können eine Instanz der Klasse „System.Diagnostics.Process“ zum Ausführen einer beliebigen ausführbaren Datei (nicht nur des Editors) verwenden. Testen Sie dies z. B. mit „calc.exe“.

Definieren der Benutzeroberfläche

Jetzt verwenden Sie die VSCT-Datei, um die Benutzeroberfläche für Ihre Erweiterung zu definieren. Sehen Sie sich die Datei „StartNotepad.vsct“ an. In dieser sind alle Definitionen der Visual Studio-Benutzeroberfläche enthalten, die Sie in Ihrer Erweiterung verwenden werden. Es handelt sich um eine XML-Datei. Sie müssen also mit vielen spitzen Klammern rechnen.

Suchen Sie nach dem Block <Groups>. Jeder Menübefehl muss zu einer Gruppe gehören, damit Visual Studio weiß, wo der Befehl angezeigt werden soll. In diesem Fall befindet sich der Befehl im Menü „Tools“, und das übergeordnete Menü ist das Hauptmenü:

<Groups>
  <Group guid="guidStartNotepadCmdSet" 
    id="MyMenuGroup" priority="0x0600">
    <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>
  </Group>
</Groups>

Machen Sie sich nicht zu viele Gedanken über die Details. Hier soll nur gezeigt werden, wo sich die wichtigen Elemente befinden. Der Befehl selbst wird im Block <Buttons> definiert:

<Button guid="guidStartNotepadCmdSet" id="cmdidStartNotepad"
  priority="0x0100" type="Button">
  <Parent guid="guidStartNotepadCmdSet" id="MyMenuGroup" />
  <Icon guid="guidImages" id="bmpPic1" />
  <Strings>
    <ButtonText>Start Notepad</ButtonText>
  </Strings>
</Button>

Sie können erkennen, dass die Schaltfläche mit einer GUID („guidStartNotepadCmdSet“, mit der Gruppen-GUID identisch) und einer ID („cmdidStartNotepad“, die ID, die Sie im Paket-Assistenten angegeben haben) definiert wird. Der Befehl ist der Gruppe untergeordnet. Er weist ein Symbol und Text auf. Das Symbol stammt aus der Symbolstandardsammlung, die im Projekt enthalten ist. Die Priorität gibt die Position dieser Schaltfläche im Menü an, wenn mehrere Befehle in der Befehlsgruppe enthalten sind. Die GUIDs und IDs für die Gruppen und Schaltflächen werden im Block <Symbols> definiert:

<!-- This is the package GUID. -->
<GuidSymbol name="guidStartNotepadPkg"
  value="{18311db7-ca0f-419c-82b0-5aa14c8b541a}" />
<!-- This is the GUID used to group the menu commands together -->
<GuidSymbol name="guidStartNotepadCmdSet"
  value="{b0692a6d-a8cc-4b53-8b2d-17508c87f1ab}">
  <IDSymbol name="MyMenuGroup" value="0x1020" />
  <IDSymbol name="cmdidStartNotepad" value="0x0100" />
</GuidSymbol>

Die Bitmaps werden ebenfalls im Block <Symbols> definiert.

<GuidSymbol name="guidImages" 
  value="{b8b810ad-5210-4f35-a491-c3464a612cb6}" >
  <IDSymbol name="bmpPic1" value="1" />
  <IDSymbol name="bmpPic2" value="2" />
  <IDSymbol name="bmpPicSearch" value="3" />
  <IDSymbol name="bmpPicX" value="4" />
  <IDSymbol name="bmpPicArrows" value="5" />
  <IDSymbol name="bmpPicStrikethrough" value="6" />
</GuidSymbol>

Versuchen Sie, das Symbol in eines der anderen hier definierten Symbole zu ändern. Keines der Symbole ist besonders für den Editor geeignet. Wählen Sie also das durchgestrichene Symbol aus, weil es einen anderen Bereich des Setups zeigt. Die Symbole werden im Block <Symbols> definiert. Sie müssen jedoch auch im Attribut „usedList“ des Blocks <Bitmaps> aufgelistet werden:

<Bitmap guid="guidImages" href="Resources\Images.png" usedList="bmpPic1,
  bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows"/>

Wie Sie sehen, wird „bmpPicStrikethrough“ nicht aufgelistet, obwohl das Symbol definiert wurde. Wenn Sie das Symbol in diese Bitmap ändern, wird es im Menü nicht angezeigt. Fügen Sie „bmpPicStrikethrough“ also hinzu:

<Bitmap guid="guidImages" href="Resources\Images.png" usedList="bmpPic1,
  bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows, bmpPicStrikethrough"/>

Nun können Sie das Symbol für die Schaltfläche des Menüs in „bmpPicStrikethrough“ ändern:

<Button guid="guidStartNotepadCmdSet" id="cmdidStartNotepad"
  priority="0x0100" type="Button">
  <Parent guid="guidStartNotepadCmdSet" id="MyMenuGroup" />
  <Icon guid="guidImages" id="bmpPicStrikethrough" />
  <Strings>
    <ButtonText>Start Notepad</ButtonText>
  </Strings>
</Button>

Nun können Sie das Ergebnis testen. Wenn die experimentelle Instanz angezeigt wird, sollte das Menü „Tools“ Abbildung 4 ähneln.

Der Befehl zum Starten des Editors
Abbildung 4 – Der Befehl zum Starten des Editors

Fügen Sie nun eine Tastenkombination für den Menübefehl „Start Notepad“ hinzu. In diesem Beispiel wird STRG+1 verwendet. Stellen Sie beim Hinzufügen einer Tastenkombination sicher, eine weniger gebräuchliche Kombination auszuwählen, damit Ihr Befehl keinen Konflikt mit einer Standardkombination bewirkt. Dieser Vorgang kann vollständig in der VSCT-Datei ausgeführt werden. Tastenkombinationen werden in der VSCT-Datei als „KeyBindings“ bezeichnet. Fügen Sie der VSCT-Datei den folgenden Block hinzu:

<KeyBindings>
  <KeyBinding guid="guidStartNotepadCmdSet" 
    id="cmdidStartNotepad"    
    editor="guidVSStd97" key1="1" mod1="CONTROL"/>
</KeyBindings>

Das Attribut „key1“ deklariert die Standardtaste, das Attribut „mod1“ den Modifizierer oder die kombinierte Taste (normalerweise STRG, ALT oder UMSCHALTTASTE), die zusammen mit der Standardtaste gedrückt wird. Wenn Sie „mod2="ALT"“ hinzufügen, um eine zweite Modifizierertaste hinzuzufügen, ergibt sich STRG+ALT+1 als Tastenkombination. Verwenden Sie vorerst STRG+1. Merken Sie sich jedoch, dass sich die VSCT-Datei gut als Ausgangspunkt für Anpassungen eignet. Jetzt können Sie mit dem Debuggen beginnen. Starten Sie das Paket erneut. Wenn die experimentelle Instanz angezeigt wird, drücken Sie STRG+1. Nun sollte eine Instanz des Editors geöffnet werden.

Sicherstellen der Reaktionsfähigkeit der Benutzeroberfläche

Die Methode „MenuItemCallback“ blockiert in ihrer aktuellen Implementierung nicht den UI-Thread. Sie können den Editor weiterhin mit dem Befehl „Start Notepad“ (oder STRG+1) starten. Auch können Sie weiterhin Aufgaben in der Visual Studio-IDE ausführen: Sie können das Fenster verschieben, in den Menüs auf andere Befehle klicken usw. Stellen Sie sich vor, Ihr Tool müsste seine Arbeit beenden, bevor Sie den Handler beenden. Anders gesagt, Sie müssen „Process.WaitForExit“ aufrufen.

Wenn Sie „WaitForExit“ für den UI-Thread von Visual Studio aufrufen, wie es durch „MenuItemCallback“ an diesem Punkt geschieht, wird die gesamte Benutzeroberfläche von Visual Studio eingefroren. Überprüfen Sie dies in der Praxis. Rufen Sie „WaitForExit“ in der Methode „MenuItemCallback“ auf:

private void MenuItemCallback(object sender, EventArgs e)
{
  Process proc = new Process();
  proc.StartInfo.FileName = "notepad.exe";
  proc.Start();
  proc.WaitForExit();
}

Beginnen Sie mit dem Debuggen, und wenn die experimentelle Instanz angezeigt wird, drücken Sie STRG+1. Nun sollte eine Instanz des Editors geöffnet werden. Versuchen Sie nun, das Visual Studio-Fenster zu verschieben (das Fenster mit der experimentellen Instanz). Es lässt sich nicht verschieben. Sie können auch keine anderen Aufgaben in der Benutzeroberfläche von Visual Studio ausführen. Möglicherweise wird sogar eine Popupmeldung mit dem Text „Microsoft Visual Studio ist ausgelastet“ angezeigt. Dieses Verhalten muss natürlich unbedingt behoben werden.

Glücklicherweise ist die Lösung einfach. Wenn Sie ein Tool oder einen Prozess verwenden, dessen Abschluss einige Zeit in Anspruch nimmt, umschließen Sie das Tool oder den Prozess in „MenuItemCallback“ mit einem Task. Das folgende Beispiel zeigt dies:

private void MenuItemCallback(object sender, EventArgs e)
{
  ThreadHelper.JoinableTaskFactory.RunAsync(async delegate
  {
    Process proc = new Process();
    proc.StartInfo.FileName = "notepad.exe";
    proc.Start();
    await proc;
  });
}

Nun sollten Sie in der Lage sein, Ihr Tool auszuführen und gleichzeitig in Visual Studio zu arbeiten.

Bereinigen des Experiments

Wenn Sie mehrere Erweiterungen entwickeln oder einfach die Ergebnisse mit verschiedenen Versionen Ihres Erweiterungscodes untersuchen, funktioniert Ihre experimentelle Umgebung ggf. nicht mehr wie erwartet. In diesem Fall sollten Sie das Zurücksetzungsskript ausführen.

Dieses Skript trägt den Namen „Zurücksetzen der experimentellen Visual Studio 2013-Instanz“ und ist im Lieferumfang des Visual Studio 2013 SDKs enthalten. Dieses Skript entfernt alle Verweise auf Ihre Erweiterungen aus der experimentellen Umgebung, damit Sie wieder bei Null anfangen können. Es gibt zwei Möglichkeiten, dieses Skript abzurufen:

  • Vom Desktop durch Suchen nach „Zurücksetzen der experimentellen Visual Studio 2013-Instanz“.
  • Über die Befehlszeile, indem Sie den folgenden Befehl ausführen:
<VSSDK installation>\VisualStudioIntegration\Tools\Bin\
        CreateExpInstance.exe /Reset /VSInstance=12.0 
       /RootSuffix=Exp && PAUSE

Bereitstellen Ihrer Erweiterung

Da Ihre Toolerweiterung nun wie gewünscht ausgeführt werden kann, können Sie sie mit Ihren Freunden und Kollegen teilen. Das ist ganz einfach, wenn diese Visual Studio 2013 installiert haben. Sie müssen ihnen nur die VSIX-Datei zur Verfügung stellen, die Sie erstellt haben. Stellen Sie sicher, dass Sie den Buildvorgang im Releasemodus ausführen.

Sie finden die VSIX-Datei für diese Erweiterung im StartNotepad-Verzeichnis „bin“. Wenn Sie die Releasekonfiguration erstellt haben, befindet sich diese in „\D:\Code\StartNotepad\StartNotepad\bin\Release\StartNotepad.vsix“.

Zum Installieren der Erweiterung muss der Benutzer alle geöffneten Instanzen von Visual Studio schließen und dann auf die VSIX-Datei doppelklicken, um den VSIX Installer zu öffnen. Die Dateien werden in das Verzeichnis „%LocalAppData%\­Microsoft\VisualStudio\12.0\Extensions“ kopiert.

Wenn der Benutzer Visual Studio dann erneut öffnet, findet er die StartNotepad-Erweiterung unter „Tools | Erweiterungen und Updates“. Er kann die Erweiterung unter „Erweiterungen und Updates“ auch deinstallieren oder deaktivieren.

Wenn Sie wissen, wie Erweiterungen erstellt werden, können Sie die Benutzeroberfläche von Visual Studio ganz individuell nach Ihren Wünschen gestalten. Und Sie können Ihre besten Produktivitätsoptimierungen und -funktionen mit der Community teilen. Microsoft ermutigt Sie ebenfalls, Ihre Erweiterungen zu veröffentlichen.

Zusammenfassung

In diesem Artikel wurde nur ein kleiner Ausschnitt dessen beschrieben, was mit Visual Studio-Erweiterungen möglich ist. Weitere Informationen zu Visual Studio-Erweiterungen im Allgemeinen finden Sie auf der Seite „Integrate Your App or Service with Visual Studio“ unter bit.ly/1zoIt59.

Ausführlichere Erläuterungen finden Sie in den Artikeln der MSDN Library im Abschnitt „Extending Visual Studio Overview“ unter bit.ly/1xWoA4k. Einige gute Codebeispiele, die Sie als Grundlage für Ihre eigene Entwicklung verwenden können, finden Sie in der Beispielsammlung in der MSDN-Beispielgalerie unter bit.ly/1xWp5eD. Sobald Sie einige Erweiterungen erstellt und veröffentlicht haben, können Sie Ihre Visual Studio-Umgebung wirklich anpassen.


Susan Norwood hat für Microsoft gearbeitet und hauptsächlich Artikel zum Visual Studio SDK verfasst. Sie hat zahlreiche Benutzer dabei unterstützt, ihre Tools in Visual Studio zu integrieren.

Doug Erickson hat 13 Jahre lang als Entwickler und technischer Autor für Microsoft gearbeitet. Er erwartet schon mit Spannung, wie Entwickler Visual Studio Community einsetzen werden, um Apps und Spiele für alle Plattformen zu entwickeln.

Unser Dank gilt den folgenden technischen Experten von Microsoft für die Durchsicht dieses Artikels: Anthony Cangialosi und Ryan Molden