Ein Visual-Studio-Add-in, das C#-Code nach Visual Basic konvertiert
Veröffentlicht: 01. Mai 2006
Von Scott Swigart
Die Funktion Paste as (Einfügen als) ist für mich zu einem unentbehrlichen Hilfsmittel geworden. Oftmals möchte ich Teile von einer Website kopieren ohne die ganze HTML-Formatierung in ein Word-Dokument zu übernehmen. Hierfür ist Paste as das richtige Werkzeug.
|
Als ich im Web auf der Suche nach einem Codebeispiel war, hat sich gezeigt, dass Paste as auch für Visual Studio nützlich ist. Anstatt aber einfach die Textformatierung umzuwandeln, könnte diese Funktion auch die Sprache des Codebeispiels konvertieren. Oft kommt es vor, dass man ein Programm in C# schreibt und ein Beispiel mit der gewünschten Funktionalität in Visual Basic findet oder umgekehrt. Möchte man derartigen Code übernehmen, muss man das Beispiel in die Zwischenablage kopieren, auf eine der vielen ausgezeichneten Codeumwandlungs-Websites gehen, dort den Code einfügen und ihn konvertieren lassen, das Ergebnis kopieren und schließlich den konvertierten Code in Visual Studio einfügen.
Wenn ich auf einer Website ein C#-Codebeispiel finde, möchte ich eigentlich ohne die Zwischenschritte zur Umwandlung kommen und einfach mit Paste as Visual Basic (Inhalte als Visual Basic einfügen) den umgewandelten Beispielcode in den Code-Editor übernehmen. Alle notwendigen Bausteine sind hierfür bereits verfügbar – um alles miteinander zu verbinden, ist lediglich noch etwas Code erforderlich.
Auf dieser Seite
Das Add-in erstellen
Zeit zum Testen
Ein Add-in hinzufügen
Umwandlungsformular
Paste As Visual Basic einbinden
Der Autor
Das Add-in erstellen
Da es eine ganze Reihe Web-basierter Codekonverter gibt, sollte der Benutzer im Add-in Paste as Visual Basic auswählen können, welchen Konverter er einsetzen möchte. Bei Webprojekten müssen Sie davon ausgehen, dass eine bestimmte Website nicht ewig betriebsfähig ist oder dass sich die Implementierung in einer Weise ändert, mit der Ihr Code nicht mehr klarkommt. Wenn Sie sich in mehr als einen Umwandlungsdienst einklinken, ist es wahrscheinlicher, dass immer mindestens ein Dienst für die Konvertierung verfügbar ist. Obendrein verwenden unterschiedliche Codekonverter unterschiedliche Algorithmen und für einen bestimmten Codeabschnitt kann ein konkreter Algorithmus besser oder schlechter arbeiten. Schließlich sollte es für das Visual-Studio-Add-in später leicht möglich sein, zusätzliche Konverter zu unterstützen.
Die Schnittstelle IConvertCode dient dazu, die Konverterimplementierung vom übrigen Code zu abstrahieren. Diese recht einfache Schnittstelle beschreibt die Umwandlungsoperation im Allgemeinen und überlässt die spezifische Implementierung anderen Klassen:
Public Interface IConvertCode Function Convert(ByVal csCode As String) As String ReadOnly Property ConverterName() As String End Interface
Die Methode Convert übernimmt C#-Code als Zeichenfolgenargument und gibt Visual-Basic-Code als Zeichenfolge zurück. Die Eigenschaft ConverterName liefert den Namen des Konverters, damit der Benutzer den gewünschten Konverter selbst wählen kann.
Die erste Implementierung dieser Schnittstelle greift auf den C#-/VB.NET-Konverter-Web-Service von Kamal Patel zurück, der momentan unter kamalpatel.net/ConvertCSharp2VB.aspx verfügbar ist. Nachdem ein Verweis auf diesen Dienst hinzugefügt wurde, ist der Code für den Aufruf recht unkompliziert, wie es Listing 1 zeigt. Die vom Web Service offen gelegte Methode Execute übernimmt C#-Code und gibt Visual-Basic-Code zurück. Da der Web Service die gleiche Signatur wie IConvertCode.Convert aufweist, lassen sich die Argumente an IConvertCode.Convert einfach an den Web Service weiterreichen und die Ergebnisse im Gegenzug übernehmen.
Listing 1: Einen Web Service zur Codekonvertierung aufrufen
Public Class WSConvert Implements IConvertCode Public Function Convert(ByVal csCode As String) As String _ Implements IConvertCode.Convert Dim codeConverter As _ New CSToVBWebService.ConvertCSharp2VBService() Return codeConverter.Execute(csCode) End Function Public ReadOnly Property ConverterName() As String _ Implements IConvertCode.ConverterName Get Return “Kamal Patel‘s Converter“ End Get End Property End Class
Ein weiteres hervorragendes Tool ist der AJAX-basierte Codekonverter von Carlos Aguilar Mares, der unter carlosag.net/Tools/CodeTranslator/Default.aspx zur Verfügung steht. Dieser Konverter wandelt zwischen C# und Visual Basic bereits während der Codeeingabe um. Hinter den Kulissen wird der Code als Satz von Formularfeldernan carlosag.net/Tools/CodeTranslator/translate.ashx gesendet. Eine weitere Implementierung von IConvertCode nutzt diese Einrichtung, um die Übersetzung durchzuführen, wie es in Listing 2 zu sehen ist.
Listing 2: Einen formularbasierten Konverter verwenden
Public Class CAConvert Implements IConvertCode Public Function Convert(ByVal csCode As String) As String _ Implements IConvertCode.Convert Dim formFields As New NameValueCollection formFields.Add(“code“, csCode) formFields.Add(“Language“, “C#“) formFields.Add(“DestinationLanguage“, “VB“) Dim client As New WebClient Return Encoding.ASCII.GetString( _ client.UploadValues( _ “http://www.carlosag.net/Tools/“ & _ “CodeTranslator/translate.ashx“, _ “POST“, formFields _ ) _ ) End Function Public ReadOnly Property ConverterName() As String _ Implements IConvertCode.ConverterName Get Return “Carlos Aguilar‘s Converter“ End Get End Property End Class
Diese Implementierung sendet den C#-Code als Formularfelder an eine Webadresse. Der Visual-Basic-Code kommt als Körper der HTTP-Antwort zurück. Der C#-Code wird mit einer NameValueCollection gesendet, wobei die C#-Quelle als code-Element hinzugefügt, die Quellsprache als Language-Element spezifiziert und das Visual-Basic-Ergebnis im DestinationLanguage-Element übernommen wird. Nachdem die Methode Convert die Auflistung gefüllt hat, sendet sie sie mithilfe der Methode WebClient.UploadValues an die Webadresse. Die Methode UploadValues sendet die Formularfelder und übernimmt die Ergebnisse als Byte-Arrays. Die Methode Encoding.ASCII.GetString konvertiert das Byte-Array wieder in eine Zeichenfolge. Diese Zeichenfolge enthält die Visual-Basic-Übersetzung.
Wie Sie sich überzeugen können, weichen zwar die internen Implementierungen der Konverter stark voneinander ab, erfüllen jedoch die Schnittstelle IConvertCode, da sie Methoden bereitstellen, die C#-Code als Zeichenfolge übernehmen und Visual-Basic-Code als Zeichenfolge zurückgeben.
Zeit zum Testen
Die Implementierungen der Codeumwandlung wurden in einem Klassenbibliotheksprojekt untergebracht. In den älteren Visual-Studio-Versionen hätte man wahrscheinlich eine einfache Windows-Form-Anwendung erstellt, um die Konverter zu testen und sich davon zu überzeugen, dass sie wie erwartet funktionieren. Die Visual Studio 2005 Team Edition stellt nun aber für Softwareentwickler integrierte Komponententesteinrichtungen bereit. Man muss lediglich mit der rechten Maustaste innerhalb einer Methode klicken und kann schnell einen Test für diese Methode generieren.
Wenn Sie erstmalig einen Komponententest erstellen, wird Ihrer Projektmappe ein neues Projekt hinzugefügt und der Testcode in diesem Projekt untergebracht. Der Komponententest für eine der Umwandlungsmethoden ist in Listing 3 zu sehen.
Listing 3: Komponententest für formularbasierte Konvertierung
<TestMethod()> _ Public Sub CAConvertTest() Dim target As IConvertCode = New CAConvert() Dim csCode As String = My.Computer.FileSystem.ReadAllText( _ DataDir & “\CSCode.txt“) Dim expected As String = My.Computer.FileSystem.ReadAllText( _ DataDir & “\CAVBCode.txt“) Dim actual As String actual = target.Convert(csCode) Assert.AreEqual(expected, actual, _ “PasteAsVB.CAConvert.Convert did not return the expected value.“) End Sub
Der Test lädt den C#-Quellcode aus einer Textdatei. Der Code wird nach Visual Basic konvertiert und mit einer anderen Datei verglichen, die die erwarteten Ergebnisse enthält. Stimmen die Ergebnisse überein, hat der Code den Test bestanden. Im Fenster des Test-Managers lassen sich die Komponententests schnell durchführen. Wenn Sie später weitere Konverter hinzufügen oder die vorhandene Logik ändern, sollten Sie sich anhand dieser Tests schnell davon überzeugen können, ob alles richtig funktioniert.
Ein Add-in hinzufügen
Nachdem Sie die ordnungsgemäße Funktion der Konverter sichergestellt haben, ist es an der Zeit, ein Add-in für Visual Studio 2005 zu erstellen. Dazu können Sie ein neues Add-in-Projekt zu Ihrer Projektmappe hinzufügen. Add-ins sind unter A Other Project Types | Extensibility (andere Projekttypen | Erweiterungen) im Dialogfeld Add New Project (Neues Projekt hinzufügen) verfügbar (siehe Abbildung 1).
Abb. 1: Ein Add-in-Projekt erstellen
Wenn Sie Name und Speicherort festgelegt und auf OK geklickt haben, startet der Visual-Studio-Add-in-Assistent und stellt Ihnen mehrere Fragen, um Sie beim Erstellen des Gerüsts für das Add-in zu unterstützen. Unter anderem legen Sie fest, ob das Addin als Eintrag im Menü Tools (Extras) erscheinen soll, ob das Add-in beim Starten von Visual Studio geladen wird und ob es mit Befehlszeilenoptionen verwendet wird (und somit keine modale Benutzeroberfläche erhält).
Im Unterschied zu Visual Studio 2003 enthält das Add-in-Projekt für Visual Studio 2005 den erforderlichen Standardcode, der das Add-in korrekt mit der Entwicklungsumgebung verbindet. Visual Studio verwendet die von der Add-in-Klasse implementierte Schnittstelle IExtensibility2, um mit dem Add-in zu kommunizieren. Wichtige Methoden wie OnConnection und QueryStatus werden automatisch erstellt. Die Methode Exec – die zum Zuge kommt, wenn der Benutzer ihr Add-in aufruft – wird ebenfalls als Stub angelegt.
Wenn Sie das Add-in als Startprojekt festlegen und F5 drücken, passiert etwas Erstaunliches: Eine neue Instanz von Visual Studio startet mit dem installierten Add-in. In dieser neuen Instanz von Visual Studio können Sie das Add-in testen. Es lassen sich sogar Haltepunkte setzen und die bekannten Debug-Funktionen verwenden – genau wie bei jedem anderen Codeabschnitt. Das Starten des Add-ins in einer Testinstanz von Visual Studio ist ein neues und sehr willkommenes Merkmal in Visual Studio 2005.
Allerdings wünscht man sich am automatisch generierten Standardcode einige Änderungen. Erstens wird das Add-in standardmäßig im Menü Tools untergebracht. Es soll aber im Menü Edit (Bearbeiten) unmittelbar nach dem Menübefehl Paste erscheinen. Der Code in Listing 4 zeigt die modifizierte OnConnection-Methode.
Listing 4: Modifizierte OnConnection-Methode
Public Sub OnConnection(ByVal application As Object, _ ByVal connectMode As ext_ConnectMode, _ ByVal addInInst As Object, _ ByRef custom As Array) Implements IDTExtensibility2.OnConnection _applicationObject = CType(application, DTE2) _addInInstance = CType(addInInst, AddIn) If connectMode = ext_ConnectMode.ext_cm_UISetup Then Dim commands As Commands2 = CType( _ _applicationObject.Commands, Commands2) Dim editMenuName As String Try Dim resourceManager As System.Resources.ResourceManager = _ New System.Resources.ResourceManager( _ “PasteAsVBAddIn.CommandBar“, _ System.Reflection.Assembly.GetExecutingAssembly()) Dim cultureInfo As System.Globalization.CultureInfo = _ New System.Globalization.CultureInfo( _ _applicationObject.LocaleID) editMenuName = resourceManager.GetString( _ String.Concat(cultureInfo.TwoLetterISOLanguageName, _ “Edit“)) Catch e As Exception editMenuName = “Edit“ End Try Dim commandBars As CommandBars = _ CType(_applicationObject.CommandBars, CommandBars) Dim menuBarCommandBar As CommandBar = commandBars.Item(„MenuBar“) Dim editControl As CommandBarControl = _ menuBarCommandBar.Controls.Item(editMenuName) Dim editPopup As CommandBarPopup = CType(editControl, CommandBarPopup) Try Dim command As Command = commands.AddNamedCommand2( _ _addInInstance, „PasteAsVBAddIn“, _ “Paste as Visual Basic“, _ “Convert the clipboard content from C# „ & _ “to Visual Basic and paste“, _ True, 59, Nothing, _ CType(vsCommandStatus.vsCommandStatusSupported,Integer)+ _ CType(vsCommandStatus.vsCommandStatusEnabled, Integer), _ vsCommandStyle.vsCommandStylePictAndText, _ vsCommandControlType.vsCommandControlTypeButton) command.AddControl(editPopup.CommandBar, 12) Catch argumentException As System.ArgumentException End Try End If End Sub
Der Standardcode für diese Methode weist einige wichtige Modifikationen auf. Zuerst schließt das Projekt eine Ressourcendatei namens CommandBar.resx ein, die den Text für die Menübefehle der obersten Ebene von Visual Studio in mehreren Sprachen enthält. Die folgende Codezeile sucht nach einem Menübefehl, dem der zweibuchstabige Landescode vorangestellt ist:
editMenuName = resourceManager. GetString( _ String.Concat(cultureInfo.TwoLetterISOLanguageName, „Edit“))
Wenn Sie diesen Code auf einem Computer ausführen, der für USEnglisch eingerichtet ist, sucht er nach einer Ressourcenzeichenfolge namens enEdit in CommandBar.resx. Ist der Computer für Deutsch eingerichtet, sucht der Code nach deEdit. Damit erhalten Sie den kulturspezifischen Text für den Menübefehl zurück, der erforderlich ist, um dieses Menüobjekt per Programm zu suchen. Nachdem das Menü der obersten Ebene lokalisiert ist, können Sie ihm Untermenüs hinzufügen. Die folgenden Codezeilen suchen das eigentliche Menüobjekt:
Dim editControl As CommandBarControl = _ menuBarCommandBar.Controls.Item(editMenuName) Dim editPopup As CommandBarPopup = CType(editControl, CommandBarPopup)
In die gefundene Menüleiste lässt sich der neue Menübefehl Paste as Visual Basic hinzufügen. Dazu wird ein Befehl erzeugt und dem Menü hinzugefügt:
Dim command As Command = commands.AddNamedCommand2( _ _addInInstance, “PasteAsVBAddIn“, “Paste as Visual Basic“, _ “Convert the clipboard content from C# to Visual Basic and paste“, _ True, 59, Nothing, _ CType(vsCommandStatus.vsCommandStatusSupported, Integer) + _ CType(vsCommandStatus.vsCommandStatusEnabled, Integer), _ vsCommandStyle.vsCommandStylePictAndText, _ vsCommandControlType.vsCommandControlTypeButton) command.AddControl(editPopup.CommandBar, 12)
Der Befehl wird dem Menü an Position 12 hinzugefügt, d.h. unmittelbar nach dem Menübefehl Paste (siehe Abbildung 2).
Abb. 2: Add-in im Menü Edit (Bearbeiten)
Zudem ist es wichtig, dass das Add-in nur aktiviert ist, wenn dies auch sinnvoll ist. Beispielsweise wird man nur Inhalte als Visual Basic einfügen, wenn man tatsächlich eine Visual-Basic-Codedatei bearbeitet. Das Aktivieren und Deaktivieren des Add-ins geschieht in der Methode QueryStatus. Der in Listing 5 gezeigte Code bewirkt, dass das Add-in nur angezeigt wird, wenn es ein aktives Dokument gibt, das mit der Erweiterung .vb endet und die Zwischenablage Text enthält.
Listing 5: Das Add-in aktivieren bzw. Deaktivieren
Public Sub QueryStatus( _ ByVal commandName As String, _ ByVal neededText As vsCommandStatusTextWanted, _ ByRef status As vsCommandStatus, _ ByRef commandText As Object) Implements IDTCommandTarget.QueryStatus If neededText = _ vsCommandStatusTextWanted.vsCommandStatusTextWantedNone Then If commandName = “PasteAsVBAddIn.Connect.PasteAsVBAddIn“ Then If _applicationObject.ActiveDocument IsNot Nothing _ AndAlso _ LCase(_applicationObject.ActiveDocument.FullName) _ .EndsWith(„.vb“) _ AndAlso My.Computer.Clipboard.GetText <> String.Empty Then status = CType(vsCommandStatus.vsCommandStatusEnabled + _ vsCommandStatus.vsCommandStatusSupported, _ vsCommandStatus) Else status = CType(vsCommandStatus.vsCommandStatusSupported, _ vsCommandStatus) End If Else status = vsCommandStatus.vsCommandStatusUnsupported End If End If End Sub
In der derzeitigen Phase der Projektentwicklung wird das Addin bereits korrekt in Visual Studio eingebunden und es ist fast einsatzbereit, um den Code zu konvertieren. Nun ist lediglich noch die Methode Exec des Add-ins mit dem Code zu verbinden, der tatsächlich die Umwandlung ausführt und die Ergebnisse in den Editor einfügt.
Umwandlungsformular
Um dem Benutzer etwas Komfort zu bieten, gibt es ein Formular, in dem der Benutzer aus verschiedenen Umwandlungsoptionen auswählen und das Ergebnis als Vorschau betrachten kann. Abbildung 3 zeigt das Umwandlungsformular. Es erscheint, wenn der Benutzer den Menübefehl Paste as Visual Basic wählt.
Abb. 3: Benutzeroberfläche für die Konvertierung
Der Fensterbereich für den C#-Quellcode zeigt den aktuellen Inhalt der Zwischenablage. In einem Listenfeld kann der Benutzer den gewünschten Konverter auswählen. Ein Klick auf die Schaltfläche Preview (Vorschau) bewirkt, dass die Ausgabe der Umwandlung im unteren Teil des Formulars erscheint. Der Benutzer kann sich somit davon überzeugen, ob das Ergebnis akzeptabel ist, bevor er den Code in die eigene Codedatei einfügt. Klicken auf Convert (Konvertieren) führt die Umwandlung aus und fügt das Ergebnis direkt in die geöffnete Codedatei ein. Wenn das Kontrollkästchen Format Code After Convert (Code nach dem Konvertieren formatieren) aktiviert ist, wird der Code neu formatiert, um die passenden Einrückungen im eingefügten Code sicherzustellen.
Der Code für das Formular ist recht einfach und verwendet die Umwandlungsklassen, die am Anfang dieses Artikels gezeigt wurden:
Private converters() As IConvertCode = { _ New PasteAsVB.CAConvert(), _ New PasteAsVB.WSConvert() _ } Private Sub ConverterForm_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load CsSourceTextBox.Text = My.Computer.Clipboard.GetText ConverterListBox.ValueMember = „ConverterName“ ConverterListBox.DisplayMember = „ConverterName“ ConverterListBox.DataSource = converters End Sub
Beim Laden des Formular wird ein Array von Konvertern instanziiert. Alle diese Konverter implementieren die Schnittstelle IConvertCode. Die Methode FormLoad bindet das Listenfeld an dieses Array und die Eigenschaft ConvertName wird zur Anzeige eingerichtet. Daraufhin erscheinen die Namen der Konverter im Listenfeld. Wenn Sie weitere Konverter hinzufügen möchten, erstellen Sie einfach zusätzliche Klassen, die IConvertCode implementieren, und fügen sie dann in das Konverterarray ein. Zudem ist es möglich, die Liste der zu verwendenden Konverter aus einer Konfigurationsdatei zu laden.
Beim Klicken auf Preview führt der ausgewählte Konverter die Umwandlung aus und die Ergebnisse erscheinen im Vorschau-Textfeld. Wenn der Benutzer auf Convert klickt, wird der umgewandelte Code einer Eigenschaft des Formulars zugewiesen und das Formular geschlossen. Der Code für die Vorschau- und die Umwandlungsfunktionalität ist in Listing 6 zu sehen.
Listing 6: Die Funktionalität für Vorschau und Konvertieren
Private Sub Preview_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Preview.Click Dim oldCursor As Cursor = Cursor Cursor = Windows.Forms.Cursors.WaitCursor Dim convertedCode As String = GetConvertedCode(CsSourceTextBox.Text) VbResultsTextBox.Text = convertedCode Cursor = oldCursor End Sub Private Sub ConvertButton_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles ConvertButton.Click Dim oldCursor As Cursor = Cursor Cursor = Windows.Forms.Cursors.WaitCursor VBCode = GetConvertedCode(CsSourceTextBox.Text) Cursor = oldCursor Me.DialogResult = Windows.Forms.DialogResult.OK End Sub Private Function GetConvertedCode(ByVal csCode As String) As String Dim converter As IConvertCode = ConverterListBox.SelectedItem Dim convertedCode As String = converter.Convert(csCode) Return convertedCode End Function
Das Umwandlungsformular ist jetzt komplett und muss nur noch aus der Methode Exec des Add-ins aufgerufen werden, wie es der Code in Listing 7 zeigt.
Listing 7: Eine Konvertierung ausführen
Public Sub Exec(ByVal commandName As String, _ ByVal executeOption As vsCommandExecOption, _ ByRef varIn As Object, ByRef varOut As Object, _ ByRef handled As Boolean) Implements IDTCommandTarget.Exec handled = False If executeOption=vsCommandExecOption.vsCommandExecOptionDoDefault Then If commandName = “PasteAsVBAddIn.Connect.PasteAsVBAddIn“ Then Dim f As New ConverterForm() If f.ShowDialog() = System.Windows.Forms.DialogResult.OK Then _applicationObject.ActiveDocument _ .Selection.Insert(f.VBCode) If f.Reformat Then _applicationObject.ExecuteCommand( _ “Edit.FormatDocument“) End If End If handled = True Exit Sub End If End If End Sub
Wenn der Benutzer das Add-in aufruft, erscheint das Umwandlungsformular. Klickt er auf die Schaltfläche Convert, wird die Umwandlung ausgeführt und die Ergebnisse werden in der Eigenschaft VBCode des Formulars gespeichert. Das Formular kehrt dann mit dem Ergebnis DialogResult.OK zurück. Das Add-in prüft das Ergebnis und fügt dann den konvertierten Code in den Code-Editor ein. Ist das Kontrollkästchen zum Formatieren aktiviert, führt das Add-in außerdem den Befehl Edit.FormatDocument aus, um die aktuelle Codedatei neu zu formatieren.
Paste As Visual Basic einbinden
Mit Visual Studio 2005 ist es ein Leichtes, Add-ins zu erstellen. Erstens generiert ein Assistent den Standardcode, der das Add-in in das Menü von Visual Studio einklinkt. Zweitens lässt sich über F5 eine Testinstanz von Visual Studio mit dem eingebundenen Add-in starten. Somit können Sie Ihr Add-in auch komfortabel debuggen.
Das im Artikel vorgestellte Add-in wandelt C#- in Visual-Basic-Code um und fügt das Ergebnis in ein Projekt ein. Das Add-in ist momentan für zwei vorhandene Web-basierte Konverter ausgelegt, aber so konstruiert, dass sich zusätzliche Konverter leicht hinzufügen lassen.
Wenn Sie das fertige Add-in lediglich installieren möchten, finden Sie im Begleitcode zu diesem Artikel (auf der Website des MSDN Magazine) ein Installationsprojekt, mit dem Sie den Befehl Paste as Visual Basic in jede beliebige Visual-Studio-2005-Entwicklungsumgebung einbinden können. Wie Sie gesehen haben, muss das Erstellen eigener Add-ins keine allzu schwierige Aufgabe sein. Falls Ihnen einmal der Gedanke kommt: „Hätte ich doch nur ein Add-in, das XYZ bewerkstelligt“, sollte es Ihnen jetzt einfach von der Hand gehen, ein derartiges Add-in selbst zu erstellen.
Der Autor
Scott Swigart beschäftigt sich als Berater, Autor und Sprecher mit aktuellen Themen zu Schlüsseltechnologien. Aus seiner Feder stammen mehrere Bücher zu .NET. Er ist zertifizieter Microsoft-Trainer (MCT) und Entwickler (MCSD) sowie Microsoft MVP. Sie erreichen ihn unter scott@swigartconsulting.com.