VB 5/6-Tipp 0021: Status einer DFÜ-Verbindung abfragen
von ActiveVB
Beschreibung
Wer wissen will, ob eine stehende DFÜ-Verbindung existiert oder nicht, kann sich mit einigen wenigen Aufrufen der RAS-APIs Gewissheit über den jeweiligen Status verschaffen.
Änderung am 14.12.2002: Zahlreiche Bugfixes und Erweiterungen!
Schwierigkeitsgrad: | Verwendete API-Aufrufe: RasEnumConnectionsA (RasEnumConnections), RasGetConnectStatusA (RasGetConnectStatus) | Download: |
'Dieser Quellcode stammt von http://www.activevb.de 'und kann frei verwendet werden. Für eventuelle Schäden 'wird nicht gehaftet. 'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. 'Ansonsten viel Spaß und Erfolg mit diesem Source! '------------- Anfang Projektdatei Project1.vbp ------------- ' Die Komponente ' (MSWINSCK.OCX)' wird benötigt. '--------- Anfang Formular "Form1" alias Form1.frm --------- ' Steuerelement: Timersteuerelement "Timer1" ' Steuerelement: Textfeld "Text1" ' Steuerelement: Beschriftungsfeld "Label1" ' Korrekturen by GFi http://www.ispf.de 14.12.2002 Option Explicit Private Declare Function RasEnumConnections Lib "RasApi32.dll" _ Alias "RasEnumConnectionsA" (lpRasCon As Any, lpcb As _ Long, lpcConnections As Long) As Long Private Declare Function RasGetConnectStatus Lib "RasApi32.dll" _ Alias "RasGetConnectStatusA" (ByVal hRasCon As Long, _ lpStatus As Any) As Long Const RAS_MaxEntryName = 256 Const RAS_MaxDeviceType = 16 Const RAS_MaxDeviceName = 128 'Änderung am 14.12.2002: nicht 32! 'Änderung am 14.12.2002: Für RasEnumConnections Rückgabewert Private Const ERROR_BUFFER_TOO_SMALL = 603 Private Type RASType dwSize As Long hRasCon As Long szEntryName(RAS_MaxEntryName) As Byte szDeviceType(RAS_MaxDeviceType) As Byte szDeviceName(RAS_MaxDeviceName) As Byte End Type ' Die magische Zahl 412... ' dwSize Long 4 Byte ' hRasCon Long 4 Byte ' szEntryName Byte 257 Byte (257, weil 0 mitzählt!) ' szDeviceType Byte 17 Byte ' szDeviceName Byte 129 Byte ' ============================ ' 411 Byte ' 411 ist ungerade, daher auf nächte Long Grenze aufrunden ' ' 411 + ((4 - 411 Mod 4)) Mod 4 = 412 Private Type RASStatusType dwSize As Long RasConnState As Long dwError As Long szDeviceType(RAS_MaxDeviceType) As Byte szDeviceName(RAS_MaxDeviceName) As Byte End Type ' + GFi Verbindungs Status Private Enum RasConnState RASCS_PAUSED = &H1000& RASCS_DONE = &H2000& RASCS_OpenPort = 0& RASCS_PortOpened = 1& RASCS_ConnectDevice = 2& RASCS_DeviceConnected = 3& RASCS_AllDevicesConnected = 4& RASCS_Authenticate = 5& RASCS_AuthNotify = 6& RASCS_AuthRetry = 7& RASCS_AuthCallback = 8& RASCS_AuthChangePassword = 9& RASCS_AuthProject = 10& RASCS_AuthLinkSpeed = 11& RASCS_AuthAck = 12& RASCS_ReAuthenticate = 13& RASCS_Authenticated = 14& RASCS_PrepareForCallback = 15& RASCS_WaitForModemReset = 16& RASCS_WaitForCallback = 17& RASCS_Projected = 18& RASCS_StartAuthentication = 19& ' nur Win 95 RASCS_CallbackComplete = 20& ' nurWin 95 RASCS_LogonNetwork = 21& ' nur Win 95 RASCS_SubEntryConnected = 22& RASCS_SubEntryDisconnected = 23& RASCS_Interactive = RASCS_PAUSED RASCS_RetryAuthentication = RASCS_PAUSED + 1& RASCS_CallbackSetByCaller = RASCS_PAUSED + 2& RASCS_PasswordExpired = RASCS_PAUSED + 3& RASCS_Connected = RASCS_DONE RASCS_Disconnected = RASCS_DONE + 1& End Enum Private Sub Form_Load() Timer1.Interval = 200 Timer1.Enabled = True End Sub Private Sub Form_Resize() Text1.Width = Me.ScaleWidth If Me.ScaleHeight > Label1.Height Then Text1.Height = Me.ScaleHeight - Label1.Height End If End Sub Private Sub Timer1_Timer() DFÜStatus End Sub Private Function StripNull(ByRef strNullTerminatedstring) As String StripNull = Left(strNullTerminatedstring, InStr(1, strNullTerminatedstring, Chr(0)) - 1) End Function Private Function DFÜStatus() As Boolean ' Änderung am 14.12.2002: Dim RAS(255) As RASType ' Warum gleich 255??? ' ' Die Funktion RasEnumConnections gibt einen Fehler zurück, ' wenn der Speicher nicht reicht. Daher... Dim RAS() As RASType ' entspricht in C++ Pointer anlegen Dim RASStatus As RASStatusType Dim lg&, lpcon&, Result& ' Änderung am 14.12.2002: Dim i As Long ReDim RAS(1) ' Änderung am 14.12.2002: RAS(0).dwSize = 412 Falsch! ' Der Fehler ist von Microsoft übernommen und weltweit verbreitet worden. RAS(0).dwSize = LenB(RAS(0)) + (4 - (LenB(RAS(0)) Mod 4)) Mod 4 ' Änderung am 14.12.2002: lg = 256 * RAS(0).dwSize ' lg ist ein Rückgabewert von der Funktion und wird nicht gesetzt! Result = RasEnumConnections(RAS(0), lg, lpcon) ' Änderung am 14.12.2002: If (Result = ERROR_BUFFER_TOO_SMALL) And (lpcon > 0) Then ' Fehler, zuwenig Speicher. ' In diesem Fall einfach das Array vergrößern. ReDim Preserve RAS(UBound(RAS()) + 1) Result = RasEnumConnections(RAS(0), lg, lpcon) ' Kommentar am 14.12.2002: man könnte dies auch in eine While Wend ' Schleife setzen. Ich bin mir allerdings nicht sicher, ' ob das Funktioniert und ob es je mehr als eine Verbindung ' geben kann. Die Funktion ist jedenfalls dafür ausgelegt. End If ' Änderung am 14.12.2002: Funktionsrückkehr ohne Fehler! If Result = 0 Then If lpcon = 0 Then Label1.Caption = "Offline" '### Text1 = "" DFÜStatus = False Else ' 'Änderung am 14.12.2002: RASStatus.dwSize = 160 ' Falsch! ' Der Fehler ist von Microsoft übernommen und weltweit verbreitet worden. RASStatus.dwSize = LenB(RASStatus) + (4 - (LenB(RASStatus) Mod 4)) Mod 4 ' Änderung am 14.12.2002: Alle Verbindungen durchgehen... For i = 0 To lpcon - 1 ' Änderung am 14.12.2002: RAS(0).hRasCon enhält das Handle der 1. DFü-Verbindung Result = RasGetConnectStatus(RAS(i).hRasCon, RASStatus) ' Änderung am 14.12.2002: GFi RASStatus.RasConnState vergleich mit Enum RasConnState If RASStatus.RasConnState = RasConnState.RASCS_Connected Then Label1.Caption = "Online" '### ' Änderung am 14.12.2002: Weitere Informationen ausgeben Text1 = StripNull(StrConv(RAS(i).szDeviceType, vbUnicode)) _ & " Verbindung: '" & _ StripNull(StrConv(RAS(i).szEntryName, vbUnicode)) _ & "' über " & _ StripNull(StrConv(RAS(i).szDeviceName, vbUnicode)) & vbCrLf DFÜStatus = True Else Label1.Caption = "DFÜ-Einwahl oder -Trennen" '### DFÜStatus = False End If Next i End If End If End Function '---------- Ende Formular "Form1" alias Form1.frm ---------- '-------------- Ende Projektdatei Project1.vbp --------------
Tipp-Kompatibilität:
Windows/VB-Version | Win32s | Win95 | Win98 | WinME | WinNT4 | Win2000 | WinXP |
VB4 | |||||||
VB5 | |||||||
VB6 |
Ihre Meinung
Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.
Archivierte Nutzerkommentare
Klicken Sie diesen Text an, wenn Sie die 15 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.
Kommentar von Stefan Ostermann am 09.12.2005 um 02:06
mache mich sofort an die Arbeit, diese API zu zerlegen
Kommentar von Gunter Schmidt am 17.11.2004 um 13:29
und noch ein kleiner Hinweis:
'ReDim RAS(1)
ReDim RAS(0)'da die Zählung bei 0 beginnt und nur eine Leitung erwartet wird
' Änderung am 14.12.2002: RAS(0).dwSize = 412 Falsch!
' Der Fehler ist von Microsoft übernommen und weltweit verbreitet worden.
RAS(0).dwSize = LenB(RAS(0)) + (4 - (LenB(RAS(0)) Mod 4)) Mod 4
lg = (UBound(RAS) + 1) * RAS(0).dwSize 'Ubound damit es möglich ist, gleich die richtige Anzahl Verbindungen abzufragen, falls diese bekannt sind (z.B. durch eine regelmäßige Abfrage)
'Ansonsten gibt es immer den Fehler ERROR_BUFFER_TOO_SMALL
'Das Programm ruft hier unnötigerweise die Funktion doppelt auf
Kommentar von Gunter Schmidt am 17.11.2004 um 11:52
Ich habe zwei Anmerkungen:
Hinweis zu:
' Änderung am 14.12.2002:
If (Result = ERROR_BUFFER_TOO_SMALL) And (lpcon > 0) Then
' Fehler, zuwenig Speicher.
' In diesem Fall einfach das Array vergrößern.
ReDim Preserve RAS(UBound(RAS()) + 1)
Result = RasEnumConnections(RAS(0), lg, lpcon)
' Kommentar am 14.12.2002: man könnte dies auch in eine While Wend
' Schleife setzen. Ich bin mir allerdings nicht sicher,
' ob das Funktioniert und ob es je mehr als eine Verbindung
' geben kann. Die Funktion ist jedenfalls dafür ausgelegt.
End If
sollte in der Tat durch
While (result = ERROR_BUFFER_TOO_SMALL) And (lpcon > 0)
' Fehler, zuwenig Speicher.
' In diesem Fall einfach das Array vergrößern.
ReDim Preserve RAS(UBound(RAS()) + 1)
result = RasEnumConnections(RAS(0), lg, lpcon)
Wend
ersetzt werden.
Zwei Leitungen gleichzeitig entstehen z.B. durch Tunnel (VPN)-Verbindungen. Hier lässt sich nicht ausschließen, dass noch mehr Verbindungen aufgebaut sind.
Weiterhin sollte angemerkt werden, dass hier nur RAS-Verbindungen geprüft werden. Kabelkunden haben quasi ein LAN, d.h. eine aktive Internetverbindung, die hier nicht erkannt würde.
Kommentar von Axel am 10.10.2004 um 14:13
Unter XP bekomme ich mit .szPhoneNumber kein Resultat.
Wenn jemand "den Dreh raus hat" wäre ich für eine kurzfristige Info dankbar. (ich bin immerhin schon über 3C)
Kommentar von Armin am 13.03.2003 um 11:13
habe problem mit der Verbindung zum internet Fehler DFÜ/RAS Verbindung besteht bereits Fehler Code 645
Kommentar von am 03.02.2003 um 10:35
Kommentar von Michael Sepp am 14.01.2003 um 17:54
Wie kann man den status einer Internetverbindung festellen, wenn mann sich nicht über eine dfü-verbindung einwählt?? Ich bentuze das Programm Fritz!web dsl .
Kommentar von Puri am 08.01.2003 um 00:31
Kann man auch irgendwie in Erfahrung bringen, wie lange eine DFÜ-Verbindung schon besteht?
Kommentar von Guido Fischer am 13.12.2002 um 20:45
>Doofe Frage: Woher kommt eigentlich die magische Zahl 412 für die Größe der RASType-Struktur (oder habe ich einen Blackout?)
*lach* ist doch ganz einfach! Du adierst einfach die Länge der Variablen zusammen. Also 4 + 4 + 256 + 16 + 32 macht gleich ... 312, ist doch logisch.
Schon interessant zu sehen, wieviele Pappnasen den falschen Source kopiert haben. Alle, wirklich ALLE habens falsch - Japaner, Koreaner, Engländer, Franzosen, Russen, Ammies.... Das kommt davon, wenn man sich auf die Bastelleien anderer Verlässt und sich dann hinterher über merkwürdige systemabstürze wundert.
die 412 erreicht man, wenn man der Konstanten RAS_MaxDeviceName den ursprünglichen Wert 128 zuweist. Ein Lenb(RAS(0)) ergibt 411. Da ungerade Speichergrenzen von der API nicht erlaubt sind, erweitert man das ganze auf +1 = 412.
RASStatus.dwSize = 160 ist auch so ein Fall. Warum 160? Na weil Lenb(RasStatus) 158 ergibt. Vielleicht wird so klarer:
RasStatus.dwSize = LenB(RasStatus) + ((4 - (LenB(RasStatus) Mod 4)) Mod 4)
Gruß, Guido
Kommentar von Roland am 09.04.2002 um 00:41
Funktionierte unter W2000, VB6, SP5 nicht: Schwerer Absturz mit Schutzspeicherverletzung, "On Error..." keine Chance.
Habe dann die Deklaration von "Byte" auf "long" geändert und dann funktionierte es...;-))
[ übernehme keine Garantie, weil ich die Konsequenzen meines Handelns nicht kenne ]
Kommentar von Jens Heling am 25.09.2001 um 20:04
Doofe Frage: Woher kommt eigentlich die magische Zahl 412 für die Größe der RASType-Struktur (oder habe ich einen Blackout?)
Kommentar von Markus Ursinus am 24.05.2001 um 15:35
Dieser Tip bringt mich schon mal weiter, danke! Aber nu bräuchte ich noch die IP die ich vom Provider zugewiesen bekomme. Hat da jemand ne Antwort ?
thx
Kommentar von Harald Dransfeld am 22.02.2001 um 17:57
Kann man mit diesem Tip auch dann die DFUE-Verbindung abfragen, wenn die Verbindung über eine ISDN-Karte hergestellt wird?
Kommentar von Ingmar Lissner am 22.10.2000 um 23:58
Ok, das mit dem LAN hat sich erledigt (bin auf dieser Seite fündig geworden), aber kann man auch Internetverbindungen über einen Decoder abfragen?
Kommentar von Ingmar Lissner am 22.10.2000 um 23:46
Kann man feststellen, ob eine Internet-Verbindung über einen Decoder (z.B. T-Online) oder über ein LAN besteht?