2017-02-20 14 views
0

今から2013年(私は3年以上)、メインのVB.Netプロジェクトでhttp://www.useragentstring.com/を使用して、追加するユーザーエージェントの文字列からブラウザの名前/バージョンおよびOS名/バージョンを取得しています統計情報をローカルのWebアプリケーションに送信します。VB.Netでbrowscap.iniを使用する

しかし、最近、このウェブサイトは、最近数ヶ月のうちに多くのダウンタイムで信頼性が低くなりました。だから私の統計情報に欠けているデータを避けるために、私はオンラインではなくローカルの解決策を探しました。私はhttp://browscap.org/がまだ更新されたユーザーエージェント情報をこの日(browscap.ini)にアップロードする古いWebサイト(1998年以降)であることを発見しました。 PHP用に設計されていますが、そこにC#の実装が見つかりました:https://www.gocher.me/C-Sharp-Browscap

しかし、VB.Net開発者として、私はVB実装を見つけられませんでした。私はたくさんのグーグル・グーグルで成功しました。誰かがVB.NETのために1つを得るか?

答えて

0

最終的にC#ソリューションをVB.NETに変換して頭を傷つけることになりました。

Public Class CompareByLength 
Implements IComparer(Of String) 
    Private Function Compare(ByVal x As String, ByVal y As String) as Integer _ 
     Implements IComparer(Of String).Compare 
      If x Is Nothing Then 
       If y Is Nothing Then 
        Return 0 
       Else 
        Return 1 
       End If 
      Else 
       If y Is Nothing Then 
        Return -1 
       Else 
        Dim retval As Integer = x.Length.CompareTo(y.Length) 
        If retval <> 0 Then 
         Return -retval 
        Else 
         return -x.CompareTo(y) 
        End If 

       End If 
      End If 
     End Function 
End Class 

Public Class BrowsCap 
    Private Declare Function GetPrivateProfileSectionNames Lib "kernel32.dll" Alias "GetPrivateProfileSectionNamesA" (ByVal lpReturnedString As Byte(), ByVal nSize As Integer, ByVal lpFileName As String) As Integer 
    Private Declare Function GetPrivateProfileSection Lib "kernel32.dll" Alias "GetPrivateProfileSectionA" (ByVal lpAppName As String, ByVal lpReturnedBuffer As Byte(), ByVal nSize As Integer, ByVal lpFileName As String) As Integer 
    Private Declare Function GetPrivateProfileString Lib "kernel32.dll" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedBuffer As String, ByVal nSize As Integer, ByVal lpFileName As String) As Integer 

    Private path As String 
    Private sections As String() 

    Private Function GetSectionNames() As String() 
     Dim maxsize As Integer = 500 
     Do 
      Dim bytes(maxsize) As Byte 
      Dim size As Integer = GetPrivateProfileSectionNames(bytes, maxsize, path) 
      If size < maxsize - 2 Then 
       Dim Selected As String = Encoding.ASCII.GetString(bytes, 0, size - (IIf(size > 0, 1, 0))) 
       Return Selected.Split(New Char() {ControlChars.NullChar}) 
      End If 
      maxsize = maxsize * 2 
     Loop 
    End Function 

    Public Sub IniFileName(ByVal INIPath As String) 
     path = INIPath 
     sections = GetSectionNames() 
     Array.Sort(sections, New CompareByLength()) 
    End Sub 

    public Function IniReadValue(ByVal Section As String, ByVal Key As String) As String 
     Dim temp As New StringBuilder(255) 
     Dim i As Integer = GetPrivateProfileString(Section, Key, "", temp.ToString(), 255, path) 
     Return temp.ToString() 
    End Function 

    Private Function findMatch(ByVal Agent As String) As String 
     If sections IsNot Nothing Then 
     For Each SecHead As String In sections 
      If (SecHead.IndexOf("*", 0) = -1) And (SecHead.IndexOf("?", 0) = -1) And (SecHead = Agent) Then 
      If IniReadValue(SecHead, "parent") <> "DefaultProperties" Then 
       Return SecHead 
      End If 
      End If 
     Next 
     For Each SecHead As String In sections 
      Try 
      If (SecHead.IndexOf("*", 0) > -1) Or (SecHead.IndexOf("?", 0) > -1) Then 
       if Regex.IsMatch(Agent, "^" + Regex.Escape(SecHead).Replace("\*", ".*").Replace("\?", ".") + "$") Then 
       Return SecHead 
       End If 
      End If 
      Catch ex As Exception 
      'Console.WriteLine(ex) 
      End Try 
     Next 
     Return "*" 
     End If 
     Return "" 
    End Function 

    Public Function getValues(ByVal Agent As String) As NameValueCollection 
     Dim match As String = findMatch(Agent) 
     Dim col As NameValueCollection = New NameValueCollection() 
     Do 
     Dim entries() As string 
     Dim goon As Boolean = true 
     Dim maxsize As Integer = 500 
     While goon 
      Dim bytes(maxsize) As Byte 
      Dim size As Integer = GetPrivateProfileSection(match, bytes, maxsize, path) 
      If size < maxsize - 2 
      Dim section As String = Encoding.ASCII.GetString(bytes, 0, size - IIf(size > 0, 1, 0)) 
      entries = section.Split(New Char() {ControlChars.NullChar}) 
      goon = False 
      End If 
      maxsize = maxsize * 2 
     End While 
     match = "" 
     If entries.Length > 0 Then 
      For Each entry As String In entries 
      Dim ent As String() = entry.Split(New Char() {"="C}) 
      If ent(0) = "Parent" Then 
       match = ent(1) 
      else if col(ent(0)) is nothing Then 
       col.Add(ent(0), ent(1)) 
      End If 
      Next 
     End If 
     Loop While match <> "" 
     Return col 
    End Function 
End Class 

そして、ここでそれを使用する方法である:

Dim dict As Dictionary(Of String, Object) = New Dictionary(Of String, Object) 
Dim bc As New BrowsCap 
bc.IniFileName(Server.MapPath("/App_Data/lite_asp_browscap.ini")) 
Dim Entry As NameValueCollection = bc.getValues(Request.UserAgent) 
For Each s As String In Entry.AllKeys 
    dict.Add(s, Entry(s)) 
Next 
' dict("Browser") will contains browser name like "IE" or "Chrome". 
' dict("Version") will contains browser version like "11.0" or "56.0". 
' dict("Platform") will contains OS name and version like "Win7". 

唯一のことはやって左に時々(週に一度のように)私のbrowscap.ini(またはlite_asp_browscap.ini)をリフレッシュすることです。

+1

PInvokeを使用するよりも、INIを読み込んで解析するのが約6倍高速であることがわかります。多分もっと簡単かもしれません。 – Plutonix

+0

あなたは正しくなければならず、私はこれを他のところで見たことがありますが、私はパーズ+ compare + regex/matchロジックを書く時間がありません。すべてはすでにC#で書かれています。また、私のコードは1日100〜200回しか実行されません。私にとってはあまり問題ではありません。しかし、PInvokeなしですでに書かれているこの種のロジックがあれば、それを投稿しても構いません。しかし、これを指摘してくれてありがとう。 –

関連する問題