Prüfen, ob URL erreichbar

  • VB.NET

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Prüfen, ob URL erreichbar

    Hallo Leute!
    Ich arbeite gerade an meinem Update-Programm.
    Dafür möchte ich gerne prüfen, ob eine URL erreichbar ist, oder nicht.
    Geschickterweise möchte ich das nicht über einen Try-Catch-Block lösen, sondern eher so:

    VB.NET-Quellcode

    1. If URLErreichbar = 1 Then 'Hierfür brauch ich den Code
    2. Msgbox("URL erreichbar!")
    3. Else
    4. Msgbox("URL nicht erreichbar!")
    5. End If


    Dabei möchte ich nicht prüfen, ob der Server erreichbar ist (Ping), sondern ob der Server einen 404-Error ausgibt.
    Also weis wie man prüfen kann, ob die URL einen 404-Error ausgibt?
    Vielen Dank im Vorraus!

    *Topic verschoben*

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Marcus Gräfe“ ()

    VB.NET-Quellcode

    1. Function URLErreichbar(ByVal URL As String) As Integer
    2. Try
    3. My.Computer.Network.Ping(URL)
    4. Return 1
    5. Catch
    6. Return 0
    7. End Try
    8. End Function


    VB.NET-Quellcode

    1. If URLErreichbar("http://google.at") = 1 Then
    2. Msgbox("URL erreichbar!")
    3. Else
    4. Msgbox("URL nicht erreichbar!")
    5. End If


    Kein Plan wie es anders geht.
    Whos Faster ALPHA: Bald....
    Hab sowas noch nie gemacht und den folgenden Code noch nich ausprobiert, aber geht das nich so?

    VB.NET-Quellcode

    1. If My.Computer.Network.Ping("http://google.de") Then
    2. MsgBox("Alles OK")
    3. Else
    4. MsgBox("Fehler!!")
    5. End If
    Also ohne Try...Catch...etc...-Zeugs
    Nein, Int32 verbrauchen 4 Bytes Speicher und nicht nur 1 Byte, wie Bools... msdn.microsoft.com/de-de/library/47zceaw7%28v=VS.90%29.aspx


    er will nicht den server fragen, ob er online ist, sondern abfragen ob eine spezielle datei zur verfügung steht. das ist nunmal nicht der sinn von ping!

    nimm einen webclient und fang alle exceptions. tritt keine auf, kann die datei abgerufen werden. tritt eine auf, kannst du auf die datei nicht zugriefen, warum auch immer. (keine rechte / datei gibts nicht etc.)

    BjöNi schrieb:

    Hab sowas noch nie gemacht und den folgenden Code noch nich ausprobiert, aber geht das nich so?

    VB.NET-Quellcode

    1. If My.Computer.Network.Ping("http://google.de") Then
    2. MsgBox("Alles OK")
    3. Else
    4. MsgBox("Fehler!!")
    5. End If
    Also ohne Try...Catch...etc...-Zeugs

    Der Server ist ja erreichbar, aber ich wollte es gerne so, dass wenn er einen 404-Error ausgibt, ne meldung kommt und wenn nicht, die datei heruntergeladen wird.
    grad reineditiert. nimm einen webclient oder webrequest. ich glaube mit dem request kann man nach einer datei fragen, ohne sie laden zu müssen. schau dir die system.net.****-klasse jeweils an.
    @FuFu^^:
    Nein, Int32 verbrauchen 4 Bytes Speicher und nicht nur 1 Byte, wie Bools... msdn.microsoft.com/de-de/library/…v=VS.90%29.aspx

    Hatte das jetzt gerade was mit meinem Post zu tun?
    Wenn ja, versteh ich nich wodrauf du raus willst...

    @Superleo1810:
    Ach so... Dann fällt mir nichts anderes als TryCatch ein...
    EDIT: Mir fällt was ein - On Error GoTo bla - noch schlimmer!

    EDIT2:
    @FuFu^^:
    meinst du "Also ohne Try...Catch...etc...-Zeugs"? Ja, das hab ich reineditiert, bevor du gepostet hast, weils mir noch eingefallen ist - was dagegen?
    Nein bjöni, das mit dem Speicher bezog sich nicht auf dich. Ich übergehe deine Posts einfach mal, weil sie auch mit dem "Try...Catch...etc...-Zeugs", wie du es nennst, nicht im geringsten dem TE bei seiner fragestellung (die du selbst nicht durchdrungen zu haben scheinst) helfen.


    Ping nutzt man um zu testen, ob Server erreichbar sind! NICHT um zu testen, ob Dateien auf Servern abrufbar sind. Alle hier bisher geposteten Lösungsvorschläge helfen dem TE nicht im geringsten.



    VB.NET-Quellcode

    1. MessageBox.Show(My.Computer.Network.Ping("http://www.vb-paradise.de/wcf/images/avatars/avatar-2532.png").ToString)
    Wenn du's nicht glaubst führe mal die Code-Zeile aus. Es kommt eine Exception, obwohl es das Bild gibt. Komisch, oder?

    VB.NET-Quellcode

    1. MessageBox.Show(My.Computer.Network.Ping("www.vb-paradise.de").ToString)
    hingegen funktioniert tadellos.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „FuFu^^“ ()

    Nach längerem durchforsten von google-ergebnissen hab ich nun das hier gefunden:

    VB.NET-Quellcode

    1. Imports System
    2. Imports System.Windows.Forms
    3. Imports System.Runtime.InteropServices
    4. Imports System.Security.Permissions
    5. ''' <summary>
    6. ''' Demo navigateError Event
    7. ''' source from:
    8. ''' http://msdn.microsoft.com/de-de/library/system.windows.forms.webbrowser.createsink.aspx
    9. ''' </summary>
    10. ''' <remarks></remarks>
    11. '''
    12. <PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
    13. Public Class Form1
    14. Inherits Form
    15. Private WithEvents wb As New WebBrowser2()
    16. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    17. wb.Dock = DockStyle.Fill
    18. Controls.Add(wb)
    19. ' Attempt to navigate to an invalid address.
    20. wb.Navigate("google.com/1/2/3/notexist/blabla/sohfohghg/3895676/259259/245/452")
    21. 'this displays the following message:
    22. 'Network Error (dns_unresolved_hostname)
    23. 'Your requested host "www.widgets.microsoft.com" could not be resolved by DNS.
    24. 'For assistance, contact your network support team.
    25. End Sub
    26. Private Sub wb_NavigateError( _
    27. ByVal sender As Object, _
    28. ByVal e As WebBrowserNavigateErrorEventArgs) _
    29. Handles wb.NavigateError
    30. ' Display an error message to the user.
    31. MessageBox.Show("Cannot navigate to " & e.Url & " status " & e.StatusCode.ToString)
    32. 'messagebox displays: "Cannot ..... status 404"
    33. End Sub
    34. End Class
    35. Public Class WebBrowser2
    36. Inherits WebBrowser
    37. Private cookie As AxHost.ConnectionPointCookie
    38. Private helper As WebBrowser2EventHelper
    39. <PermissionSetAttribute(SecurityAction.LinkDemand, _
    40. Name:="FullTrust")> Protected Overrides Sub CreateSink()
    41. MyBase.CreateSink()
    42. ' Create an instance of the client that will handle the event
    43. ' and associate it with the underlying ActiveX control.
    44. helper = New WebBrowser2EventHelper(Me)
    45. cookie = New AxHost.ConnectionPointCookie(Me.ActiveXInstance, helper, GetType(DWebBrowserEvents2))
    46. End Sub
    47. <PermissionSetAttribute(SecurityAction.LinkDemand, _
    48. Name:="FullTrust")> Protected Overrides Sub DetachSink()
    49. ' Disconnect the client that handles the event
    50. ' from the underlying ActiveX control.
    51. If cookie IsNot Nothing Then
    52. cookie.Disconnect()
    53. cookie = Nothing
    54. End If
    55. MyBase.DetachSink()
    56. End Sub
    57. Public Event NavigateError As WebBrowserNavigateErrorEventHandler
    58. ' Raises the NavigateError event.
    59. Protected Overridable Sub OnNavigateError(ByVal e As WebBrowserNavigateErrorEventArgs)
    60. RaiseEvent NavigateError(Me, e)
    61. End Sub
    62. ' Handles the NavigateError event from the underlying ActiveX
    63. ' control by raising the NavigateError event defined in this class.
    64. Private Class WebBrowser2EventHelper
    65. Inherits StandardOleMarshalObject
    66. Implements DWebBrowserEvents2
    67. Private parent As WebBrowser2
    68. Public Sub New(ByVal parent As WebBrowser2)
    69. Me.parent = parent
    70. End Sub
    71. Public Sub NavigateError(ByVal pDisp As Object, _
    72. ByRef URL As Object, ByRef frame As Object, _
    73. ByRef statusCode As Object, ByRef cancel As Boolean) _
    74. Implements DWebBrowserEvents2.NavigateError
    75. ' Raise the NavigateError event.
    76. Me.parent.OnNavigateError(New WebBrowserNavigateErrorEventArgs( _
    77. CStr(URL), CStr(frame), CInt(statusCode), cancel))
    78. End Sub
    79. End Class
    80. End Class
    81. ' Represents the method that will handle the WebBrowser2.NavigateError event.
    82. Public Delegate Sub WebBrowserNavigateErrorEventHandler(ByVal sender As Object, _
    83. ByVal e As WebBrowserNavigateErrorEventArgs)
    84. ' Provides data for the WebBrowser2.NavigateError event.
    85. Public Class WebBrowserNavigateErrorEventArgs
    86. Inherits EventArgs
    87. Private urlValue As String
    88. Private frameValue As String
    89. Private statusCodeValue As Int32
    90. Private cancelValue As Boolean
    91. Public Sub New( _
    92. ByVal url As String, ByVal frame As String, _
    93. ByVal statusCode As Int32, ByVal cancel As Boolean)
    94. Me.urlValue = url
    95. Me.frameValue = frame
    96. Me.statusCodeValue = statusCode
    97. Me.cancelValue = cancel
    98. End Sub
    99. Public Property Url() As String
    100. Get
    101. Return urlValue
    102. End Get
    103. Set(ByVal value As String)
    104. urlValue = value
    105. End Set
    106. End Property
    107. Public Property Frame() As String
    108. Get
    109. Return frameValue
    110. End Get
    111. Set(ByVal value As String)
    112. frameValue = value
    113. End Set
    114. End Property
    115. Public Property StatusCode() As Int32
    116. Get
    117. Return statusCodeValue
    118. End Get
    119. Set(ByVal value As Int32)
    120. statusCodeValue = value
    121. End Set
    122. End Property
    123. Public Property Cancel() As Boolean
    124. Get
    125. Return cancelValue
    126. End Get
    127. Set(ByVal value As Boolean)
    128. cancelValue = value
    129. End Set
    130. End Property
    131. End Class
    132. ' Imports the NavigateError method from the OLE DWebBrowserEvents2
    133. ' interface.
    134. <ComImport(), Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D"), _
    135. InterfaceType(ComInterfaceType.InterfaceIsIDispatch), _
    136. TypeLibType(TypeLibTypeFlags.FHidden)> _
    137. Public Interface DWebBrowserEvents2
    138. <DispId(271)> Sub NavigateError( _
    139. <InAttribute(), MarshalAs(UnmanagedType.IDispatch)> _
    140. ByVal pDisp As Object, _
    141. <InAttribute()> ByRef URL As Object, _
    142. <InAttribute()> ByRef frame As Object, _
    143. <InAttribute()> ByRef statusCode As Object, _
    144. <InAttribute(), OutAttribute()> ByRef cancel As Boolean)
    145. End Interface


    dabei versucht der webbrowser auf die seite "google.com/1/2/3/notexist/blabla/sohfohghg/3895676/259259/245/452" zuzugreifen, die natürlich nicht existiert, und tatsächlich kommt eine error404-msgbox.
    nun möchte ich es aber so machen, dass FALLS die URL abrufbar ist, das update gestartet wird, und falls nicht, eine entsprechende messagebox gezeigt wird.
    gibt es da ne lösung?

    Superleo1810 schrieb:

    Geschickterweise möchte ich das nicht über einen Try-Catch-Block lösen

    Was ist deiner Meinung nach geschickt daran ?

    Superleo1810 schrieb:

    GAlso weis wie man prüfen kann, ob die URL einen 404-Error ausgibt?

    Ja, die Seite aufrufen und den zurückgegebenen Statuscode prüfen: der wird allerddings immer in einem Catch-Block erschien, was ja auch vollkommen in Ordnung ist.
    Den kürzesten Request den Du meiner Meinung nach absetzten kannst ist der HTTP "HEAD" Request: der fragt nur den Server ob die Datei da ist und welche Länge sie hat. Punkt.

    Obwohl einem bei einer solchen Funktion CheckURL als erstes ein Boolean Wert einfällt: sicher ist nur, dass beim Http 200 (=OK) die Datei da ist. Ansonsten können alle möglichen anderen Http-Codes Gründe haben warum die Datei eben nicht /nicht mehr oder nur noch nicht erreichbar ist. Willst Du explizit den 404 (NotFound) abfragen so kommt Webstatus.ProtocolError dem am nächsten (+ Abfrage der Message). Man kann natürlich auch statt dem HttpWebRequest auf tiefer liegende Klassen (TCPClient / Sockets ausweichen und den Request manuell in den Stream schreiben).

    Hier mal eine Möglichkeit:
    HEAD Request

    VB.NET-Quellcode

    1. Function Check(ByVal url As String, Optional ByVal timeout As Integer = 20000) As Boolean
    2. Dim uri As Uri = Nothing, response As HttpWebResponse = Nothing, request As HttpWebRequest
    3. ' check valid uri
    4. If Not (url.StartsWith("http") OrElse url.StartsWith("https")) Then url = "http://" & url
    5. ' create webrequest
    6. Try
    7. request = CType(WebRequest.Create(url), HttpWebRequest)
    8. request.Method = "HEAD" : request.Timeout = timeout
    9. response = CType(request.GetResponse, HttpWebResponse)
    10. ' header enthalten zum beispiel die Länge der Datei
    11. Dim headers = response.Headers ' nicht benötigt
    12. Debug.Print(headers.ToString) ' nicht benötigt
    13. Catch ex As WebException
    14. Debug.Print("Exception;: {0}", ex.Status)
    15. ' 404
    16. If ex.Status = WebExceptionStatus.ProtocolError Then Return (False)
    17. ' rethrow
    18. Throw
    19. Finally
    20. If response IsNot Nothing Then response.Close()
    21. End Try
    22. ' all OK
    23. Return True
    24. End Function


    Der WebBrowser ist nun eher einer der langsamsten und aufwändigsten Alternativen ...
    @jan99 Nein.
    In Zeile 7 würde eine Timeout-Exception geworfen werden, dann ginge es in Zeile 13 / 14 weiter.
    ====
    Edit:
    Im Finally wird in jedem Falle aufgeräumt, was aufzuräumen ist (sofern implementiert).
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    Moin!

    erst einmal danke - aber was bedeutet das Throw?

    Aus den Dingen, die ich recherchiert habe, bin ich nicht schlau geworden!

    Habe für einen Test einmal eine ungültige URL abgeprüft und bei dem Throw kommt folgende Meldung:

    {"Der Remotename konnte nicht aufgelöst werden: 'ma23-bagis-001'"}


    ... sodass sich mein Skript aufhängt. Das soll es aber nicht ! Wie würde ich das in Griff bekommen?


    Gruß Jan

    jan99 schrieb:

    Throw
    löst die zu spezifizierende Exception aus oder reicht die aktuelle Exception an den Aufrufer weiter:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Try
    3. If Not IO.File.Exists("c:\Temp\Blub.bla") Then
    4. Throw New IO.FileNotFoundException("Nicht gefunden", "Blup.bla") ' Exception auslösen
    5. End If
    6. 'DoIt
    7. Catch ex As IO.FileNotFoundException ' genau diese abfangen
    8. If Not IO.File.Exists("c:\Temp\Blub.bla") Then
    9. MessageBox.Show("Die Datei ist ja immer noch nicht da")
    10. Throw ' zum Aufrufer durchreichen
    11. End If
    12. End Try
    13. End Sub
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    jan99 schrieb:

    Vorteil
    Dazu musst Du das Umfeld verstehen. Gugst Du hier.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!