Aufrufen von .NET Framework-Funktionen aus vorhandenen Visual Basic 6.0-Anwendungen

Veröffentlicht: 04. Jul 2006

Von Scott Swigart

Viele Entwickler gehen davon aus, dass ihnen beim Schreiben von Code in Visual Basic ® ** 6.0 die große Welt von Microsoft** ® .NET Framework verschlossen bleibt. In diesem Artikel soll bewiesen werden, dass dies nicht zutrifft. Ich möchte zeigen, wie Sie auf einfache Weise alle Elemente von .NET Framework 2.0 von vorhandenen Visual Basic 6.0-Anwendungen aus mithilfe der so genannten Visual Basic Fusion-Technik nutzen können. Verstehen Sie mich nicht falsch, ich empfehle nichts weniger, als einige Ihrer Anwendungen in Visual Basic 6.0 zu lassen. Es gibt jedoch keinen Grund, dass der Zugang zur .NET Framework-Klassenbibliothek dauerhaft verschlossen bleibt, nur weil Sie sich gegen eine Aktualisierung auf Visual Basic 2005 entschieden haben.

Der Code kann hier heruntergeladen werden:
VBFusion05.exe (150 KB)

Auf dieser Seite

Der günstige und einfache Ansatz
Aufrufen von .NET Framework
Jetzt haben Sie es – Jetzt haben Sie es nicht
Etwas Altes und etwas Neues
Schlussbemerkung
Der Autor

Warum also nicht einfach aktualisieren? Wenn Sie eine Visual Basic 6.0-Anwendung auf Visual Basic 2005 aktualisieren, stehen Ihnen zahlreiche Ressourcen zur Verfügung. Visual Studio® bietet einen Assistenten zur Migration, der automatisch einen Großteil Ihres Visual Basic 6.0-Codes neu schreibt. Microsoft hat ein Handbuch für die Migration von Visual Basic 6.0 nach Visual Basic 2005 veröffentlicht, das ein Tool zur Einschätzung der Dauer und der Kosten einer Anwendungsaktualisierung enthält. Das Web bietet unzählige Artikel, Anleitungen, Tipps und Tricks zu bestimmten Aktualisierungsthemen. Es gibt sogar einige Bücher zu diesem Thema. Angesichts einer derartigen Anzahl von Ressourcen ist die Frage berechtigt, warum Code in Visual Basic 6.0 verbleiben sollte. Warum nicht einfach den gesamten Code aktualisieren?

Tatsächlich handelt es sich bei der Codeaktualisierung von Visual Basic 6.0 auf Visual Basic 2005 um einen arbeitsintensiven Prozess, dessen Erfolg hauptsächlich von zwei Faktoren abhängt: der Codequalität und der Erfahrung des Entwicklers mit Visual Basic 2005 und .NET Framework. Modulare Anwendungen mit einer sinnvollen Architektur können einfacher aktualisiert werden als Anwendungen, die mit der Zeit in Unordnung geraten sind.

Im Visual Basic 6.0-Universum befinden sich viele Anwendungen über Jahre in der Entwicklung. Möglicherweise erforderten sie kurzfristige, ungeplante Erweiterungen von Features. Möglicherweise wurden sie von verschiedenen Entwicklern programmiert, von denen einige nicht die Zeit oder die Geduld aufbringen konnten, den geänderten Code vollständig zu verstehen. Programmierer stehen aus unterschiedlichen Gründen häufig unter dem Druck, ein Projekt in Gang zu bringen und sich sofort um das nächste zu kümmern. Daher kann der Code im Laufe der Zeit recht unübersichtlich werden. Ausgesprochen unübersichtlicher Code sollte nicht aktualisiert, sondern neu geschrieben werden – ein Vorgang, der weder günstig noch einfach ist.

Aus Sicht der Entwickler ist das Aktualisieren einer komplexen, wichtigen Visual Basic 6.0-Anwendung eine furchtbare Methode, um Visual Basic 2005 in Gang zu bringen. Daher ist es wichtig, vor dem Aktualisieren über ausreichende Erfahrungen mit .NET zu verfügen. Das hat mehrere Gründe. Wenn Sie eine Visual Basic 6.0-Anwendung an den Assistenten zur Migration übergeben und ihn ausführen, kommt als Ergebnis eine Visual Basic 2005-Anwendung heraus, die nicht ohne weiteres kompiliert und ausgeführt werden kann. Der Assistent zur Migration verteilt überall im Code Kommentare, die nicht automatisch migrierbare Stellen kennzeichnen. Um die Anwendung reparieren und wieder ausführen zu können, benötigen Sie fortgeschrittene Kenntnisse von Visual Basic 2005 und .NET Framework. Die erforderlichen Änderungen am Code umfassen alles von einfachen bis hin zu aufwendigen Bearbeitungen oder dem erneuten Schreiben gesamter Anwendungssubsysteme. Dadurch wird deutlich, dass eine Aktualisierung nicht immer einfach ist.

Nachdem die Aktualisierung als ein derart unerfreulicher Ausblick beschrieben wurde, wundern Sie sich möglicherweise, warum sie überhaupt jemand durchführt. Das Migrieren einer Codebasis nach Visual Basic 2005 ist keine einfache Aufgabe, es handelt sich jedoch um die beste Methode für reibungslosen Zugriff auf das vollständige .NET Framework. Ich empfinde es außerdem als weitaus produktiver, mit den umfassenden .NET Framework-Klassenbibliotheken und den hervorragenden Produktivitätsfunktionen von Visual Studio 2005 zu entwickeln. Visual Studio 2005 lässt Visual Studio 6.0 tatsächlich sehr alt aussehen. Bei der Aktualisierung müssen Sie für jede Anwendung eine eigene Entscheidung treffen. Lohnt sich der Aufwand? Ist eine sofortige Aktualisierung praktikabel?

Der günstige und einfache Ansatz

Eine weitere Möglichkeit besteht darin, die Anwendung in Visual Basic 6.0 zu belassen und sie jeweils in .NET Framework aufzurufen. .NET Framework beinhaltet integrierte Klassen zum Abrufen von Ping-Signalen für IP-Adressen, zum Ändern der Netzwerkverbindung, zum Übertragen von Dateien mit FTP, für den Zugriff auf COM-Ports, zur Wiedergabe von Sounds, zum Abrufen von Betriebssystem- (z. B. den physischen Speicher und die Bildschirmauflösung), Benutzer- und Domäneninformationen, zum Lesen und Schreiben im Ereignisprotokoll, für den Zugriff auf Leistungsindikatoren, zum Starten und Anhalten von Diensten sowie für den Zugriff auf die Registrierung. Diese Liste ließe sich beliebig fortsetzen. Bei der Beschreibung der .NET Framework 2.0-Klassenbibliothek kommt einem unweigerlich der Begriff "umfassend" in den Sinn. Mithilfe von .NET Framework 2.0 können Sie Abhängigkeiten von Steuerelementen von Drittanbietern sowie viele Win32®-API-Aufrufe beseitigen. Das Aufrufen in .NET Framework von Visual Basic 6.0 aus ist einfach und birgt kaum Risiken. Außerdem ist es eine gute Möglichkeit, die Visual Basic 2005-Programmierung zu beschleunigen.

Um, wie in diesem Artikel beschrieben, in .NET Framework aufrufen zu können, benötigen Sie entweder Visual Studio 2005 oder Visual Basic Express. Visual Basic Express beinhaltet alle Toolbox-Steuerelemente, IntelliSense®, Debugger und viele der Projektelemente. Es reicht somit für die ersten Versuche mit Visual Basic 2005 voll aus. Außerdem handelt es sich bei Visual Basic Express nicht um eine Probeversion, die irgendwann nicht mehr funktioniert. Es ist lediglich eine Version von Visual Studio mit eingeschränkten Funktionen, die so lange verwendet werden kann, bis die verfügbare Funktionalität nicht mehr ausreicht.

Sie sollten auch den zu diesem Artikel gehörenden Code herunterladen. Dies gilt insbesondere, wenn Sie Visual Basic Express verwenden. Kopieren Sie die Datei ComClass.zip in den Ordner \Eigene Dokumente\Visual Studio 2005\Templates\ItemTemplates\Visual Basic. Sie werden sehen, dass dieses (in Visual Basic Express nicht standardmäßig enthaltene) Projektelement wichtig ist, wenn von Visual Basic 6.0 in .NET Framework aufgerufen wird.

Aufrufen von .NET Framework

Visual Basic 6.0 eignet sich gut zum Aufrufen von COM-Objekten. Bei den Klassen in .NET Framework handelt es sich jedoch nicht um COM-Objekte. Sie können nicht direkt aus Visual Basic 6.0 aufgerufen werden. Die .NET Framework-Klassen müssen stattdessen über einen Wrapper aufgerufen werden. Die Wrapper werden mithilfe des COM-Klassenelements erstellt und verhalten sich wie alle anderen COM-Objekte. Die Wrapper können von Visual Basic 6.0, Visual Basic Scripting Edition (VBScript), Visual Basic für Applikationen (VBA) oder jeder anderen COM-kompatiblen Umgebung aufgerufen werden. Die Wrapperinterna werden in Visual Basic 2005 erstellt und können problemlos Aufrufe in .NET Framework durchführen (siehe Abbildung 1).

.NET-Wrapper für Visual Basic 6.0
Abbildung 1: .NET-Wrapper für Visual Basic 6.0

Das Erstellen von Wrappern ist eine ausgesprochen einfache Aufgabe. Anhand der folgenden Schritte können Sie einen COM-aufrufbaren Wrapper für die Ping-Funktion in .NET Framework 2.0 erstellen.

  1. Starten Sie entweder Visual Studio 2005 oder Visual Basic Express.

  2. Erstellen Sie ein neues Klassenbibliotheksprojekt mit dem Namen FX20Wrapper.

  3. Wählen Sie das Menü Projekt und anschließend Neues Element hinzufügen aus.

  4. Wählen Sie die Vorlage für COM-Klassenelemente aus. Geben Sie als Namen NetworkWrapper ein, und klicken Sie auf Hinzufügen.

  5. Fügen Sie der Klasse NetworkWrapper folgende Elemente hinzu:

    Public Function Ping(ByVal hostNameOrAddress As String, _
    Optional ByVal timeout As Integer = -1)
    If timeout >= 0 Then
    Return My.Computer.Network.Ping(hostNameOrAddress, timeout)
    Else
    Return My.Computer.Network.Ping(hostNameOrAddress)
    End If
    End Function
    

Das war's! Mit nur einigen wenigen Codezeilen haben Sie ein COM-Objekt erstellt, mit dem Sie Ping-Signale für alle im erforschten Universum vorhandenen IPv4-Adressen abrufen können. Mithilfe dieser Funktion können Sie Ping-Signale für Hostnamen oder IP-Adressen abrufen. Sie können außerdem einen optionalen Timeoutwert festlegen. Stellen Sie sich einfach einmal die Möglichkeiten vor. Nun müssen Sie lediglich noch im Menü Erstellen das Visual Basic Express-Projekt kompilieren. Die IDE kompiliert Ihr Projekt und gibt eine DLL aus, die Visual Studio als COM-Objekt registriert.

Anschließend können Sie ein Visual Basic 6.0-Projekt erstellen, das diesen Wrapper verwendet.

  1. Starten Sie Visual Basic 6.0, und erstellen Sie ein neues Standard-EXE-Projekt.

  2. Erstellen Sie eine Benutzeroberfläche wie die in Abbildung 2 dargestellte.

    Ping-Test
    Abbildung 2: Ping-Test

  3. Wählen Sie im Menü Projekt die Option Verweise aus, um FX20Wrapper einen Verweis hinzuzufügen. Beachten Sie, dass Ihr .NET-Projekt wie jedes andere COM-Objekt angezeigt wird.

  4. Fügen Sie dem Klickereignis der Schaltfläche Ping folgenden Code hinzu:

    Private Sub Command1_Click()
    Dim network As FX20Wrapper.NetworkWrapper
    Set network = New FX20Wrapper.NetworkWrapper
    Text2 = Text2 & "Pinging " & Text1 & "..."
    DoEvents
    If network.ping(Text1) Then
    Text2 = Text2 & "Responded" & vbCrLf
    Else
    Text2 = Text2 & "Did not respond" & vbCrLf
    End If
    End Sub
    
  5. Führen Sie die Anwendung aus, geben Sie eine IP-Adresse ein, und klicken Sie auf die Schaltfläche Ping. Das Ergebnis sollte dem in Abbildung 2 ähneln.

Jetzt haben Sie es – Jetzt haben Sie es nicht

Von Anwendungen wird verstärkt erwartet, dass sie mit unerwarteten Änderungen der Netzwerkverbindung umgehen können. Laptops werden getrennt. Benutzer wechseln von einem WLAN ins nächste. Das Betriebssystem benachrichtigt den Benutzer, ob das Netzwerk vorhanden oder nicht vorhanden ist. Wäre es nicht schön, wenn das Betriebssystem auch Ihre Anwendung benachrichtigen würde? In Visual Basic 2005 erfolgt diese Benachrichtigung. Das Objekt My.Computer.Network löst immer dann ein Ereignis aus, wenn sich der Status der Netzwerkverbindung ändert. Der Code in Abbildung 3 zeigt, wie Sie Ihre NetworkWrapper-Klasse um diese Benachrichtigung erweitern können.

Beachten Sie, dass My.Computer.Network in der neuen Unterroutine (dem Konstruktor des NetworkWrapper-Objekts) ein NetworkAvailabilityChanged-Ereignis auslöst. Dieses Ereignis ist nicht direkt COM-anwendbar. Es wird stattdessen mit der Unterroutine My_NetworkAvailabilityChanged des Wrappers verknüpft. Von dieser Routine wird ein COM-anwendbares Ereignis ausgelöst. Sie löst ihr eigenes NetworkAvailabilityChanged-Ereignis aus, das einen einfachen booleschen Wert enthält, der den Netzwerkstatus angibt.

Von Visual Basic 6.0 aus ist dieses Ereignis genauso einfach anwendbar wie ein Button_Click-Ereignis. Den Code für die Visual Basic 6.0-Anwendung finden Sie in Abbildung 4. Durch eine kleine Menge zusätzlichen Code werden Ihre Visual Basic 6.0-Anwendungen plötzlich netzwerkfähig. In einer Anwendung, in der dieser Wrapper implementiert wurde, wird in der Statusleiste der Status als "Offline" angezeigt, und der Zugriff auf Netzwerkressourcen möglicherweise deaktiviert, wenn das Netzwerk nicht verfügbar ist.

Etwas Altes und etwas Neues

Die ursprünglichen RFCs für FTP wurden 1973 veröffentlicht und FTP ist nach wie vor eines der beliebtesten Protokolle zum Übertragen von Dateien im Internet. Microsoft hat mit Microsoft Internet Transfer Control und der WinInet-API stets Programmunterstützung für FTP angeboten. Bis vor kurzem gab es jedoch keine systemeigene Unterstützung für FTP als Teil von .NET Framework. .NET Framework 2.0 fügt mit den Klassen WebClient, FtpWebRequest und FtpWebResponse eine Unterstützung für FTP hinzu. Mithilfe dieser Klassen können verschiedene FTP-Vorgänge durchgeführt werden. Die jeweiligen Vorgänge und die zugeordneten FTP-Befehle werden in den WebRequestMethods.Ftp-Membern beschrieben (siehe Abbildung 5).

Die für das Herunterladen einer Datei benötigte Zeit kann je nach Dateigröße und Netzwerkbandbreite erheblich variieren. Um diesem Umstand gerecht zu werden, unterstützen die FTP-Klassen sowohl synchrone als auch asynchrone Vorgänge. Synchrone Vorgänge sind am einfachsten zu programmieren. Ein Download erfordert hier nur einige wenige Visual Basic 2005-Codezeilen:

Dim w As New WebClient
w.DownloadFile(address, fileName)

Synchrone Anwendungen sperren jedoch die Anwendung (bzw. frieren diese ein), bis der Downloadvorgang abgeschlossen ist. Dieses Verhalten kann sich für Befehlszeilen- oder Stapelvorgänge eignen, es ist jedoch für Benutzer verwirrend, wenn eine Anwendung einfach nicht mehr reagiert, ohne dass darauf hingewiesen wird, wann sie wieder zur Verfügung steht. Bei asynchronen FTP-Vorgängen erfolgt der Download in einem separaten Thread. Außerdem werden Ereignisse ausgelöst, die den Fortschritt und Abschluss des Downloads anzeigen. Abbildung 6 zeigt einen Wrapper für FTP-Klassen, die sowohl synchrone als auch asynchrone Vorgänge ermöglichen.

Die FTPWrapper-Klasse baut auf den bisher dargelegten Konzepten auf. Zunächst wird die Klasse mithilfe der Projektelementvorlage ComClass erstellt. Dadurch wird sichergestellt, dass FTPWrapper die erforderlichen GUIDs für die Registrierung als COM-Objekt enthält. Eine Instanz von WebClient ist auf der Klassenebene als WithEvents dimensioniert. Dadurch können die Methoden innerhalb der Klasse auf diese einzelne Instanz zugreifen. Außerdem kann die FTPWrapper-Klasse die WebClient DownloadProgressChanged- und DownloadFileCompleted-Ereignisse verarbeiten.

Die Unterroutine DownloadFile beinhaltet eine einzige Codezeile und führt einen synchronen Download einer bestimmten Datei durch. Wie bereits beschrieben, friert Ihre Anwendung durch das Aufrufen dieser Unterroutine während des Herunterladens der Datei ein.

DownloadFileAsync ist eine vielseitigere und interessantere Methode für den Dateidownload. Diese Unterroutine stellt zunächst sicher, dass kein anderer asynchroner Vorgang ausgeführt wird. Wenn dies der Fall ist, gibt die Unterroutine eine Ausnahme aus, bei der es sich um die Visual Basic 2005 Entsprechung von Err.Raise handelt. Anschließend verwendet DownloadFileAsync die FtpWebRequest-Klasse, um einen SIZE FTP-Befehl auszuführen, der die Größe der angeforderten Datei in Bytes zurückgibt. Die Dateigröße muss bekannt sein, damit der Downloadfortschritt genau angezeigt werden kann. Abschließend wird die Funktion WebClient DownloadFileAsync aufgerufen. Diese Funktion initiiert im Hintergrund den Dateidownloadprozess und löst außerdem das Ereignis DownloadProgressChanged aus.

Das Ereignis WebClient DownloadProgressChanged ist nicht direkt COM-anwendbar, daher wird es ebenfalls gewrappt. Der Handler für DownloadProgressChanged löst ein neues Ereignis aus, das einfache Ganzzahlargumente für die heruntergeladenen Bytes und die Gesamtdateigröße weitergibt. Dieses Ereignis kann von Visual Basic 6.0 einfach angewendet werden. Entsprechend wird auch das Ereignis DownloadFileCompleted gewrappt und ist somit für Visual Basic 6.0 anwendbar.

Wrapper werden hauptsächlich deshalb erstellt, um .NET Framework-Klassen als typische COM-Objekte mit benutzerfreundlichen Eigenschaften, Methoden und Ereignissen erscheinen zu lassen. FTPWrapper erfüllt dieses Ziel. In Abbildung 7 sehen Sie den zum Herunterladen einer Datei mithilfe von FTP erforderlichen Visual Basic 6.0-Code.

Das Starten eines Downloads ist genauso einfach wie das Dimensionieren der FTPWrapper-Klasse und das Aufrufen der Unterroutinen DownloadFile oder DownloadFileAsync. Wenn Sie DownloadFileAsync aufrufen, löst FTPWrapper während des Downloads DownloadProgressChanged-Ereignisse und beim Abschluss des Downloads ein DownloadFileCompleted-Ereignis aus. Das Ereignis DownloadProgressChanged empfängt die Anzahl der bereits heruntergeladenen Bytes sowie die Gesamtdateigröße. Diese Informationen reichen für eine Downloadfortschrittsanzeige aus. Abbildung 8 zeigt den Visual Basic 6.0-FTP-Client während eines Downloads.

In Visual Basic 6.0 implementierter FTP-Client
Abbildung 8: In Visual Basic 6.0 implementierter FTP-Client

Der Codedownload für diesen Artikel beinhaltet die Wrapperklasse und die im Artikel gezeigten Beispielanwendungen. Um die Beispiele auszuprobieren, laden Sie einfach den Code herunter, und führen Sie die darin enthaltene Datei install.bat aus. Dadurch wird die Wrapperklasse als COM-Objekt registriert. Anschließend können Sie alle Visual Basic 6.0-Beispiele ausführen.

Schlussbemerkung

Visual Basic 6.0 ist das neue COBOL. Wobei dies nicht als negative Aussage über die beiden Sprachen gedacht ist. COBOL war äußerst erfolgreich, da es sich als Sprache zur Entwicklung von entscheidenden Mainframe-Anwendungen durchgesetzt hat. Als immer mehr Clients und grafische Benutzeroberflächen auftauchten, bildete Visual Basic die Hülle und erwies sich als die wohl beste Sprache für viele Geschäftsumgebungen.

Mir fällt keine etablierte Programmiersprache ein, die vollkommen verschwunden ist. Genauso wie es nach wie vor Millionen von COBOL-Zeilen gibt und in absehbarer Zeit noch geben wird, werden wir uns auch in den kommenden Jahren weiterhin mit Visual Basic 6.0 befassen. Tatsächlich hat sich Microsoft verpflichtet, die Visual Basic 6.0-Laufzeit auch mit Windows Vista™ auszuliefern. Außerdem wird unter Windows Vista die Visual Basic 6.0-Kompatibilitätssuite ausgeführt, sodass Visual Basic 6.0-Anwendungen auch zukünftig funktionieren.

Was soll jedoch mit all dem veralteten Code geschehen? Sicher ist es nicht praktikabel, jede einzelne Zeile in Visual Basic 2005 neu zu schreiben. Selbst wenn große Teile des Codes nach und nach migriert werden, mag es derzeit nicht möglich sein, die Zeit und das Risiko einzugehen, um eine Anwendung sofort zu migrieren. Verschiedene Sachzwänge werden dazu führen, dass viele Anwendungen weiterhin in der Visual Basic 6.0-Laufzeit verbleiben. Diese Anwendungen müssen jedoch nicht auf .NET Framework und die damit einhergehenden Produktivitätsvorteile verzichten.

Sie haben gesehen, wie ein kleiner Aspekt von .NET Framework, nämlich einige wenige Netzwerkklassen, gewrappt und als COM-Objekte ausgegeben werden können. Dadurch sind sie in Visual Basic  6.0 einfach zu verwenden. Alle Teile von .NET Framework können auf diese Weise gewrappt und ausgegeben werden. Betrachten Sie .NET Framework als ein Geschenk von Microsoft mit abertausenden von Klassen. Um sie zu verwenden, müssen Sie lediglich das Geschenkpapier bereitstellen.

Der Autor

Scott Swigart verbringt seine Zeit damit, über das Konvergieren und Erweitern von Technologien zu schreiben, Vorträge zu halten und zu beraten. Scott hat mehrere Bücher zu .NET geschrieben, er ist ein zertifizierter Microsoft-Trainer (MCT) und -Entwickler (MCSD) sowie ein Microsoft MVP. Sie können sich unter http://msdn.microsoft.com/msdnmag/issues/06/05/WrapItUp/ an Scott wenden.