Nachrichten im NT-Netzwerk verschicken
Veröffentlicht: 09. Okt 2003 | Aktualisiert: 27. Jun 2004
Von Mathias Schiffer
Die Microsoft Newsgroups sind eine Quelle schier unerschöpflichen Wissens, das nahezu auf Knopfdruck abrufbar ist: Hunderte deutschsprachige Entwickler vom Einsteiger bis zum Profi treffen sich hier täglich virtuell, um Fragen zu stellen oder zu beantworten. Auch themennahe Probleme, Ansichten und Konzepte werden miteinander diskutiert. Sie kennen die Microsoft Newsgroups noch nicht? Detaillierte Information für Ihre Teilnahme finden Sie auf der Homepage der Microsoft Support Newsgroups.
Diese Kolumne greift regelmäßig ein besonders interessantes oder häufig nachgefragtes Thema aus einer der Entwickler-Newsgroups auf und arbeitet es aus.
Aus der Visual Basic Newsgroup microsoft.public.de.vb:
Frage: Von der Kommandozeile aus kann ich mit "NET SEND" Kurznachrichten im Netzwerk versenden. Wie kann ich dieses Ziel auch mit Visual Basic 5 oder Visual Basic 6 erreichen?
Mit Hilfe von "NET SEND" können Sie Kurznachrichten zwischen Rechnern in einem Netzwerk versenden. Dabei ist keine Magie im Spiel, sondern allein die Unicode-basierende API-Funktion NetMessageBufferSend.
Die "NET SEND"-Messagebox in gutartiger Aktion
Voraussetzungen
Damit der Nachrichtenversand auf diese Weise funktioniert, sind zwei Voraussetzungen notwendig:
Zum einen müssen sendender und empfangender Rechner der Windows NT-Familie angehören, also als Betriebssysteme Windows NT 3.51 oder 4.0, Windows 2000, Windows XP oder Windows Server 2003 einsetzen.
Weiterhin muss der Windows-Dienst "Nachrichtendienst" gestartet worden sein. Letzteres ist nach einer Standard-Windowsinstallation gegeben. Nachdem sich jedoch seit gut einem Jahr auch Spammer diesen Dienst räuberisch zu Nutze gemacht haben, um ihre lästigen Werbenachrichten aufzuzwingen, werden sie ihn bei vielen Rechnern, die direkt an das Internet angeschlossen sind, deaktiviert finden (und falls Sie Opfer solcher Werbefenster sind und ihre Herkunft bisher nicht verstanden - deaktivieren Sie diesen Dienst auf Ihrem Rechner).
Schließlich bedarf es unter bestimmten Konstellationen hinreichender Rechte, um die Funktion erfolgreich aufrufen zu können. Diese Szenarien finden Sie in der Dokumentation zur Funktion NetMessageBufferSend im Detail beschrieben. Im einfachsten Fall ist kein bestimmtes Recht notwendig, um die Funktion auf der lokalen Maschine ausführen zu können.
Implementation
Der Aufbau der Funktion NetMessageBufferSend bereitet weiter keine Schwierigkeiten. Im Platform SDK ist sie wie folgt beschrieben:
NET_API_STATUS NetMessageBufferSend( LPCWSTR servername, LPCWSTR msgname, LPCWSTR fromname, LPBYTE buf, DWORD buflen );
Die notwendige Umsetzung in einen Declare-Prototyp für Visual Basic ist entsprechend sehr einfach:
Private Declare Function NetMessageBufferSend _ Lib "netapi32" ( _ ByVal servername As String, _ ByVal msgname As String, _ ByVal fromname As String, _ ByVal buf As String, _ ByVal buflen As Long _ ) As Long
Klären wir kurz die Bedeutung der einzelnen Parameter ab:
servername: Hier wird der Name des Computers im Netzwerk angegeben, auf dem die Funktion ausgeführt werden soll. Im Windows-Netzwerk muss er mit zwei Backslash-Zeichen ("\\") beginnen. Wird dieser Parameter mit einem Nullstring (vbNullString) bedient, wird der lokale Computer als Nachrichtenüberbringer verwendet.
msgname: In diesem Parameter wird der Empfänger der Nachricht angegeben.
fromname: In diesem Parameter geben Sie den Absender an. Wird dieser Parameter mit einem Nullstring (vbNullString) bedient, so wird der Name des lokalen Computers als Absenderangabe verwendet.
buf: Dieser String enthält den Text der Nachricht, die den bzw. die Empfänger erreichen soll.
buflen: In diesem Parameter wird übergeben, wie viele Bytes der Parameter buf enthält.
Bei der Anwendung der Funktion ist es notwendig zu berücksichtigen, dass sie ausschließlich in einer Unicode-Version existiert. Daher müssen alle String-Parameter ausdrücklich in Unicode-Notation übergeben werden. Hierfür ist kein größerer Aufwand notwendig als die Umwandlung der Strings mithilfe der VB-eigenen StrConv-Funktion.
Beispielcode Im folgenden Beispielcode finden Sie ein Anwendungsbeispiel für die Funktion NetMessageBufferSend inklusive aller notwendiger API-Deklarationen und Fehlerauswertungen. Weiterhin wird vor dem Aufruf der Funktion geprüft, ob die Betriebssystem-Voraussetzung senderseitig erfüllt ist. Verwenden Sie diesen Beispielcode in einem Standardmodul, um die Nutzung der Funktion auszuprobieren.
Tipp: Kopieren Sie den gesamten Quelltext zunächst in WRITE.EXE und erst von dort aus in Ihre Entwicklungsumgebung, um den Verlust von Zeilenumbrüchen zu vermeiden.
Option Explicit ' Standardmodul ' ------------------------------------------------------ ' - Nachrichten im NT-Netzwerk verschicken - ' ------------------------------------------------------ ' - Beispiel zum Aufruf der API-Funktion NetMessage- - ' - BufferSend unter Windows NT/2000/XP/Server 2003. - ' - (c) 2003 by Mathias Schiffer / <A href="mailto:Schiffer@mvps.org">Schiffer@mvps.org</A> - ' ------------------------------------------------------ ' ' Beispielaufruf: ' --------------- ' If Send(Recipient:="Arbeitsbiene", _ ' Sender:="Cheffe", _ ' Message:="Schluss mit Arbeit: Umtrunk " & _ ' "mit Grillgut im Dachgarten!") Then ' MsgBox "Die frohe Botschaft wurde verbreitet!" ' Else ' MsgBox "Doch lieber nochmal anrufen..." ' End If ' ------------------------------------------------------ ' Fehlerkonstante für NetMessageBufferSend: Private Const NERR_SUCCESS As Long = 0& Private Const ERROR_ACCESS_DENIED As Long = 5& Private Const ERROR_NOT_SUPPORTED As Long = 50& Private Const ERROR_INVALID_PARAMETER As Long = 87& Private Const NERR_BASE As Long = 2100& Private Const NERR_NETWORKERROR As Long = (NERR_BASE + 36&) Private Const NERR_NAMENOTFOUND As Long = (NERR_BASE + 173&) ' Ermittlung des Betriebssystems (hier: Prüfung auf NT) Private Const VER_PLATFORM_WIN32_NT As Long = 2& Private Type OSVERSIONINFO OSVSize As Long dwVerMajor As Long dwVerMinor As Long dwBuildNumber As Long PlatformID As Long szCSDVersion As String * 128 End Type Private Declare Function GetVersionEx _ Lib "kernel32" Alias "GetVersionExA" ( _ ByRef VersionInformation As OSVERSIONINFO _ ) As Long ' NET SEND-Funktionalität per NetMessageBufferSend Private Declare Function NetMessageBufferSend _ Lib "netapi32" ( _ ByVal Servername As String, _ ByVal msgname As String, _ ByVal fromname As String, _ ByVal buf As String, _ ByVal buflen As Long _ ) As Long ' ------------------------------------------------------ Public Function Send(Optional ByVal Recipient As String, _ Optional ByVal Message As String, _ Optional ByVal Sender As String, _ Optional ByVal Servername As String) _ As Boolean ' Prfe, ob ein NT-Betriebssystem vorliegt: If Not IsWinNT Then ' Funktion nicht ausführbar MsgBox "Die Send-Funktion kann nur auf Rechnern mit einem " & _ "Betriebssystem der Windows NT-Familie verwendet " & _ "werden.", _ vbCritical, "Send-Funktion" Exit Function End If ' Wurde ein Servername übergeben, muss die ' UNC-Konvention eingehalten werden: <A href="file://SERVERNAME/">\\SERVERNAME</A> If Len(Servername) > 0 Then If Left$(Servername, 1) <> "\" Then Servername = "\" & Servername End If If Left$(Servername, 2) <> "\\" Then Servername = "\" & Servername End If End If ' Umwandeln der Angaben in Unicode-Strings: If Len(Recipient) > 0 Then Recipient = StrConv(Recipient, vbUnicode) Else Recipient = vbNullString End If If Len(Message) > 0 Then Message = StrConv(Message, vbUnicode) Else Message = vbNullString End If If Len(Sender) > 0 Then Sender = StrConv(Sender, vbUnicode) Else Sender = vbNullString End If If Len(Servername) > 0 Then Servername = StrConv(Servername, vbUnicode) Else Servername = vbNullString End If ' Gibt NetMessageBufferSend 0 zurück, war der Aufruf ' erfolgreich. Select Case NetMessageBufferSend(Servername, Recipient, _ Sender, Message, _ Len(Message)) Case 0 ' Der Aufruf war erfolgreich Send = True ' Alle anderen Rückgaben signalisieren Fehler: Case ERROR_ACCESS_DENIED MsgBox "Zugriff verweigert.", _ vbCritical, "Send-Funktion" Case ERROR_INVALID_PARAMETER MsgBox "Ein übergebener Parameter ist ungültig.", _ vbCritical, "Send-Funktion" Case ERROR_NOT_SUPPORTED MsgBox "Netzwerkanfrage wird nicht unterstützt.", _ vbCritical, "Send-Funktion" Case NERR_NAMENOTFOUND MsgBox "Benutzername wurde nicht gefunden.", _ vbCritical, "Send-Funktion" Case NERR_NETWORKERROR MsgBox "Allgemeiner Netzwerkfehler.", _ vbCritical, "Send-Funktion" Case Else MsgBox "Unbekannter Fehler.", _ vbCritical, "Send-Funktion" End Select End Function Private Function IsWinNT() As Boolean ' Gibt zurück, ob es sich um ein Betriebssystem der ' Windows NT-Familie handelt (Windows NT, Windows 2000, ' Windows XP, Windows Server 2003) oder nicht. Dim OSV As OSVERSIONINFO OSV.OSVSize = Len(OSV) If GetVersionEx(OSV) <> 0 Then IsWinNT = (OSV.PlatformID = VER_PLATFORM_WIN32_NT) End If End Function ' ------------------------------------------------------