COM-Add-Ins mit Visual Basic 2008 Express Edition

Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.

Für die Erstellung von COM-Add-Ins brauchte man bislang teure Werkzeuge – so schien es zumindest. Mit ein wenig Bastelei können Sie diese jedoch auch mit der kostenlosen Express Edition von Visual Basic 2008 selber bauen. Dies eröffnet eine Menge Möglichkeiten – aber lesen Sie doch einfach selbst.

COM-Add-Ins sind praktische Helferlein, die immer zu Diensten sind, wenn auch Access geöffnet ist. Im Beitrag Permanenter Query-Analyzer (s. Shortlink 544) haben wir ein solches Tool auf Basis von Visual Basic 6.0 vorgestellt, das jedoch ausschließlich mit Access 2007 zusammenarbeitet. Im vorliegenden Beitrag lernen Sie die Grundlagen kennen, um solche Add-Ins unter .NET und ohne das kostenpflichtige Visual Studio 6.0, dafür aber mit dem kostenlosen Visual Basic 2008 Express Edition zu programmieren. Mit Visual Basic 2008 können Sie COM-Add-Ins für Office 2003 und Office 2007 programmieren.

Voraussetzung für den Einsatz von COM-Add-Ins, die mit Visual Basic 2008 erstellt wurden, ist das .NET-Framework. Dieses ist jedoch genau wie Visual Basic 2008 Express Edition kostenlos, in der aktuellen Version genau genommen sogar zusammen mit diesem erhältlich.

Das ist der gravierende Nachteil gegenüber VB6-COM-Add-Ins, die ja meist einfach in Form einer DLL daherkommen und lediglich registriert werden müssen, damit man sie einsetzen kann.

Mit der Zeit wird man allerdings auch davon ausgehen können, dass beinahe jeder Windows-Rechner dieses Framework enthält. Außerdem sind COM-Add-Ins im Gegensatz zu den mit Access entwickelten Anwendungen ja auch eher Entwicklerwerkzeuge, die nicht für ein großes Zielpublikum vorgesehen sind, sondern nur für Entwickler, und deren Arbeitsrechner ist ja meist ohnehin mit halbwegs moderner Software ausgestattet.

Ein COM-Add-In besteht aus einer oder mehreren Funktionen, die vom Benutzer über die Menüleiste beziehungsweise Symbolleiste oder bei Access 2007 über das Ribbon aufgerufen werden können und entweder reinen in dem Add-In enthaltenen Code ausführt oder aber auch eine eigene Benutzeroberfläche zur Verfügung stellen, wie es beim QueryAnalyzer der Fall ist.

Im Hintergrund

COM-Add-Ins implementieren eine spezielle Schnittstelle namens IExtensibility. Diese liefert einige Ereignisprozeduren, die etwa beim Starten oder Schließen von Access ausgelöst werden. Damit Access beispielsweise beim Starten merkt, dass es da ein COM-Add-In gibt, dessen Ereignisse es feuern soll, trägt man das COM-Add-In in geeigneter Form in die Registry ein.

Access liest beim Start nach, ob dort COM-Add-Ins eingetragen sind, merkt sich diese und ruft deren Ereignisse auf. Da diese die Schnittstelle IDTExtensibility implementieren, das heißt, die dort definierten Methoden enthalten muss, benötigen Sie auch diese Schnittstelle in Form der Datei extensibility.dll.

Nun kommt diese Schnittstelle entweder mit einer der Vollversionen von Visual Studio 2008, für die man tief ins Portemonnaie greifen muss, oder mit einer älteren Version von Visual Studio. Und das war auch eines der größten Probleme beim Erstellen der Beispielanwendungen für diesen Beitrag: Es schien keine Möglichkeit zu geben, die extensibility.dll bereitzustellen, da diese offiziell nicht für Visual Basic 2008-Projekte verfügbar ist.

In der Annahme, dass die extensibility.dll auch nur mit Wasser kocht und keine weiteren Funktionen außer der Definition der Schnittstelle besitzt, erfolgten einige erfolglose Versuche, die extensibility.dll selbst herzustellen. Nach einigen Experimenten war es schließlich geschafft: Die in Visual Basic 2008 Express Edition fehlende IDTExtensibility2-Schnittstelle ließ sich mit eben jenem Produkt nachbauen.

Bevor wir zum Bau des eigentlichen COM-Add-Ins kommen finden Sie nachfolgend die Kurzanleitung zum Eigenbau der extensibility.dll.

IDTExtensibility2 selbst bauen

Die folgenden Ausführungen gehen von einem System mit Office 2003 und Visual Studio 2008 Express Edition aus. Wer eine Version höher als die Standard Edition besitzt, dürfte die extensibility.dll bereits auf dem System haben und kann diese gegebenenfalls auch weitergeben – in diesem Bereich konnten für diesen Beitrag mangels Professional-Version keine Nachforschungen angestellt werden. Mehr Informationen zu Visual Basic 2008 Express Edition und zur Installation der Software erhalten Sie im Beitrag Visual Basic 2008 Express Edition (Shortlink 580).

Nach dem Ã-ffnen von Visual Studio legen Sie ein neues Projekt des Typs Klassenbibliothek mit dem Namen Extensibility an, ändern auch den Namen der einzigen vorhandenen Klasse von Class1.vb in Extensibility.vb und fügen den Code aus Listing 1 in die Klasse ein (den bestehenden Inhalt löschen Sie zuvor).

Listing 1: Code der Schnittstellendatei Extensibility.vb

Imports System.Runtime.InteropServices

p class=”quellcode-funktionssammlung”>Public Enum ext_ConnectMode

 ext_cm_AfterStartup = 0

p class=”quellcode-funktionssammlung”> ext_cm_Startup = 1

 ext_cm_External = 2

p class=”quellcode-funktionssammlung”> ext_cm_CommandLine = 3

 ext_cm_Solution = 4

p class=”quellcode-funktionssammlung”> ext_cm_UISetup = 5

End Enum

p class=”quellcode-funktionssammlung”>Public Enum ext_DisconnectMode

 ext_dm_HostShutdown = 0

p class=”quellcode-funktionssammlung”> ext_dm_UserClosed = 1

 ext_dm_UISetupComplete = 2

p class=”quellcode-funktionssammlung”> ext_dm_SolutionClosed = 3D

End Enum

p class=”quellcode-funktionssammlung”><ComImport(), _

 Guid("B65AD801-ABAF-11D0-BB8B-00A0C90F2744"), _

p class=”quellcode-funktionssammlung”> TypeLibType(TypeLibTypeFlags.FAggregatable Or TypeLibTypeFlags.FHidden), _

 InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _

p class=”quellcode-funktionssammlung”>Public Interface IDTExtensibility2

 <DispId(1)> Sub OnConnection( _

p class=”quellcode-funktionssammlung”> <[In](), MarshalAs(UnmanagedType.IDispatch)> ByVal Application As Object, _

 <[In]()> ByVal ConnectMode As ext_ConnectMode, _

p class=”quellcode-funktionssammlung”> <[In](), MarshalAs(UnmanagedType.IDispatch)> ByVal AddInInst As Object, _

 <[In](), MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VarEnum.VT_VARIANT)> ByRef custom As _

pre>System.Array)
<DispId(2)> Sub OnDisconnection( _p class=”quellcode-funktionssammlung”> <[In]()> ByVal RemoveMode As ext_DisconnectMode, _

 <[In](), MarshalAs(UnmanagedType.SafeArray, safearraysubtype:=VarEnum.VT_VARIANT)> ByRef custom As _

pre>System.Array)
<DispId(3)> Sub OnAddInsUpdate( _p class=”quellcode-funktionssammlung”> <[In](), MarshalAs(UnmanagedType.SafeArray, safearraysubtype:=VarEnum.VT_VARIANT)> ByRef custom As _

System.Array)
 <DispId(4)> Sub OnStartupComplete( _

p class=”quellcode-funktionssammlung”> <[In](), MarshalAs(UnmanagedType.SafeArray, safearraysubtype:=VarEnum.VT_VARIANT)> ByRef custom As _

System.Array)
 <DispId(5)> Sub OnBeginShutdown( _

p class=”quellcode-funktionssammlung”> <[In](), MarshalAs(UnmanagedType.SafeArray, safearraysubtype:=VarEnum.VT_VARIANT)> ByRef custom As _

System.Array)
End Interface

p>Wenn Sie die Einfügemarke im Codefenster auf der Zeile Public Interface IDTExtensibility2 positionieren, sollte das Eigenschaftsfenster den Wert True für die Eigenschaft COM-sichtbar anzeigen – sonst holen Sie dies nach.

Damit nicht nur das Interface, sondern die gesamte Assembly COM-sichtbar ist, öffnen Sie mit einem Klick auf My Project im Projektmappen-Explorer die Eigenschaften, zeigen dort die Registerseite Anwendung an und klicken auf die Schaltfläche Assemblyinformationen… Dort aktivieren Sie die Option Assembly COM-sichtbar machen (siehe Bild 1).

missing image file

Bild 2: Signieren der Assembly

Nun signieren Sie die Assembly noch: Dazu wechseln Sie erneut zu den Projekteigenschaften, zeigen dort die Registerseite Signierung an, aktivieren die Option Assembly registrieren… und wählen aus dem Kombinationsfeld Schlüsseldatei mit starkem Namen auswählen den Eintrag <Neu…> aus (siehe Bild 2). Folgen Sie den übrigen Anweisungen und schließen Sie den Vorgang ab.

missing image file

Bild 1: So machen Sie die Assembly COM-sichtbar

Erstellen Sie dann das Projekt mit Erstellen|Extensibility erstellen, schließen Sie das Projekt mit dem Menüeintrag Datei|Projekt schließen und geben Sie dort das Verzeichnis an, in dem Sie das Projekt speichern wollen – beispielsweise das dort üblicherweise vorgeschlagene C:\Dokumente und Einstellungen\André\Eigene Dateien\Visual Studio 2008\Projects.

Nun müssen Sie die DLL noch registrieren, wozu Sie das Tool regasm.exe mit dem folgenden Aufruf verwenden (<Pfad zur DLL> entsprechend ersetzen):

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe <Pfad zur DLL>\Extensibility.dll" /tlb /codebase

Dies erzeugt eine zusätzliche Datei namens Extensibility.tlb (die Endung tlb steht für Type Library), die Informationen über die angebotenen Member der DLL enthält.

Fertig – die Arbeiten an der Extensibility.dll sind beendet.

COM-Add-In Basisrezept

Dann kann es losgehen – die Schritte, die zu einer herkömmlichen COM-DLL führen, finden Sie hier in Kurzform:

Legen Sie mit der Vorlage Klassenbibliothek ein neues Projekt namens aiuCOMAddIn an und benennen Sie die automatisch erzeugte Klasse in aiuCOMAddIn.vb um. Die Klasse enthält nun diese beiden Zeilen:

Public Class aiuCOMAddIn
End Class

Stellen Sie dem Public-Schlüsselwort den Ausdruck <ComClass()> voran. Visual Studio zeigt den Klassennamen aiuCOMAddIn nun unterschlängelt an. Wenn Sie mit Ansicht|Fehlerliste die Fehlerliste einblenden, sehen Sie den Grund: Es fehlt ein öffentlicher Member, damit von außen via COM auf die Klasse zugegriffen werden kann.

Das bedeutet nichts weiter, als dass eine Methode fehlt, die etwa Access aufrufen kann, wenn es startet und dies dem Add-In mitteilen möchte (dazu fehlt freilich noch ein passender Eintrag in der Registry, aber dazu später mehr).

Dieser Member ist eine der fünf Prozeduren, die es auf Basis der Schnittstelle IDTExtensibility2 zu implementieren gilt. Und dazu muss man der Klasse erst einmal bekanntgeben, dass sie dies überhaupt tun soll. Dazu brauchen Sie zunächst einen Verweis auf die soeben erstellte Schnittstellenklasse Extensibility.dll.

Um diesen hinzuzufügen, öffnen Sie aus dem Projektmappen-Explorer den Eintrag My Project und wechseln dort zur Registerseite Verweise. Mit einem Klick auf Hinzufügen öffnen Sie den Dialog Verweis hinzufügen. Dort wechseln Sie auf Durchsuchen und wählen die zuvor frisch erzeugte Extensibility.DLL aus. Wechseln Sie dann zur Datei aiuCOMAddIn.vb und geben Sie dort in die noch leere Klasse die folgende Zeile ein:

Implements Extensibility.IDTExtensibility2

Visual Studio wird nun automatisch die Ereignisprozeduren der Schnittstelle hinzufügen (siehe Bild 3).

missing image file

Bild 3: Die Schnittstelle Extensibility.IDTExtensibility2 mit ihren Ereignisprozeduren

Die Methode OnConnection wird beim Ã-ffnen der Client-Anwendung, die auf das COM-Add-In zugreifen soll, ausgelöst. Ergänzen Sie diese durch eine einfache MsgBox-Anweisung:

Public Sub OnConnection(...) _
Implements Extensibility._
IDTExtensibility2.OnConnection
MsgBox("aiu")
End Sub

Schließen und speichern Sie das Projekt nun im gewünschten Verzeichnis, öffnen Sie es erneut und erstellen Sie es mit Projekt|aiuCOMAddIn erstellen. Nun fehlen noch zwei kleine Schritte. Als Erstes registrieren Sie das COM-Add-In in der Eingabeaufforderung mit dieser Anweisung:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe <Pfad zur DLL>\aiuCOMAddIn.dll" /tlb /codebase

Anschließend erzeugen Sie noch einen Registry-Eintrag, den Access beim Ã-ffnen ausliest und auf eventuell einzubindende COM-Add-Ins untersucht.

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

Testzugang

eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar