Dateien aus Commandline/String filtern

  • VB.NET

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

    Dateien aus Commandline/String filtern

    Moin Moin,

    ich hoffe ihr könnt mir mal auf die schnelle helfen.

    Ich möchte gerne alle Dateien aus einem String rausfiltern.
    z.B:
    C:\Dir\Dir\App.exe -Arg1
    (Rausfiltern: C:\Dir\Dir\App.exe)
    \??\C:\Dir\Dir\App.exe -Arg1 C:\MahText.txt
    (Rausfiltern: C:\Dir\Dir\App.exe, C:\MahText.txt)
    App.exe -Arg1 %WinDir%\Explorer.exe %SystemRoot%\System32\RunDLL32.exe
    (Rausfiltern: C:\Windows\System32\App.exe, C:\Windows\Explorer.exe, C:\Windows\System32\RunDLL32.exe)
    Nur beispiele wie ich dass meine.

    Gibt es eine passende Funktion in der Win API oder ähnliches?

    Hier meine Manuelle such-funktion:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.Text.RegularExpressions
    3. Imports System.Text
    4. Imports System.Runtime.InteropServices
    5. Public Class Form1
    6. <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    7. Public Shared Function SearchPath(ByVal path As String, ByVal fileName As String, ByVal extension As String, ByVal numBufferChars As Integer, ByVal buffer As StringBuilder, ByVal filePart As Integer()) As Integer
    8. End Function
    9. Function SearchFile(ByRef sFile As String) As String
    10. Dim nResult As Long
    11. Dim sBuffer As New StringBuilder(280)
    12. nResult = SearchPath(Nothing, sFile, Nothing, 280, sBuffer, Nothing)
    13. If nResult > 0 Then
    14. Return sBuffer.ToString
    15. Else
    16. Return ""
    17. End If
    18. End Function
    19. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    20. '############# AUFRUF #############
    21. TextBox3.Text = String.Join(vbNewLine, CleanPath(TextBox1.Text))
    22. '############# AUFRUF #############
    23. End Sub
    24. Function CleanPath(ByVal sPath As String) As String()
    25. For Each s As String In {" ", "!\??", "\??", "@"}
    26. While (sPath.StartsWith(s))
    27. sPath = sPath.Remove(0, s.Length)
    28. End While
    29. Next
    30. Static SYSTEM_PATH As String = Environment.GetFolderPath(Environment.SpecialFolder.System)
    31. Static WINDOWS_PATH As String = SYSTEM_PATH.Replace("\system32", "")
    32. If sPath.StartsWith("\systemroot", StringComparison.CurrentCultureIgnoreCase) Then
    33. sPath = SYSTEM_PATH & "" & sPath.Remove(0, "\systemroot".Length)
    34. End If
    35. For Each s As String In RegExMatchList(sPath, "\%(.*?)\%", RegexOptions.IgnoreCase)
    36. s = s.Replace("%", "")
    37. If (String.IsNullOrEmpty(s)) Then Continue For
    38. Dim sVarPath As String = Environment.GetEnvironmentVariable(s)
    39. If (String.IsNullOrEmpty(sVarPath)) Then sVarPath = ""
    40. sPath = sPath.Replace("%" & s & "%", sVarPath)
    41. Next
    42. Dim aList As New List(Of String)
    43. Dim isMark As Boolean = False
    44. Dim SB As New StringBuilder
    45. For Each s As String In sPath.Split(CChar(" "))
    46. If (String.IsNullOrEmpty(s)) Then Continue For
    47. Dim iMarks As Integer = s.Split(CChar("""")).Length - 1
    48. If (StrContains(s, """", False) AndAlso iMarks = 1) Then
    49. isMark = (Not isMark)
    50. ElseIf (iMarks > 1) Then
    51. s = s.Replace("""", "")
    52. If (FileExist(s)) Then
    53. aList.Add(SearchFile(s))
    54. End If
    55. Continue For
    56. End If
    57. If (isMark) Then
    58. SB.Append(s & " ")
    59. ElseIf (SB.Length > 0) Then
    60. SB.Append(s)
    61. SB.Replace("""", "")
    62. If (FileExist(SB.ToString)) Then
    63. aList.Add(SearchFile(SB.ToString))
    64. End If
    65. SB.Length = 0
    66. End If
    67. If (FileExist(s)) Then
    68. aList.Add(SearchFile(s))
    69. End If
    70. Next
    71. Return aList.ToArray
    72. End Function
    73. Function RegExMatch(ByVal Text As String, ByVal Filter1 As String, ByVal Options As RegexOptions) As String
    74. For Each m As Match In Regex.Matches(Text, Filter1, Options)
    75. Return m.Value
    76. Next
    77. Return ""
    78. End Function
    79. Function RegExMatchList(ByVal Text As String, ByVal Filter1 As String, ByVal Options As RegexOptions) As String()
    80. Dim aList As New List(Of String)
    81. For Each m As Match In Regex.Matches(Text, Filter1, Options)
    82. aList.Add(m.Value)
    83. Next
    84. Return aList.ToArray
    85. End Function
    86. Function FileExist(ByRef sFile As String, Optional ByVal bSearchFor As Boolean = True) As Boolean
    87. If (bSearchFor) Then
    88. Return (IO.File.Exists(sFile) OrElse IO.File.Exists(SearchFile(sFile)))
    89. Else
    90. Return IO.File.Exists(sFile)
    91. End If
    92. End Function
    93. Function StrEqual(ByRef sString1 As String, ByRef sString2 As String, Optional ByVal bCaseSensivite As Boolean = True) As Boolean
    94. If (bCaseSensivite) Then
    95. Return String.Equals(sString1, sString2, StringComparison.CurrentCulture)
    96. Else
    97. Return String.Equals(sString1, sString2, StringComparison.CurrentCultureIgnoreCase)
    98. End If
    99. End Function
    100. Function StrContains(ByRef sString1 As String, ByRef sString2 As String, Optional ByVal bCaseSensivite As Boolean = True) As Boolean
    101. If (bCaseSensivite) Then
    102. Return (sString1.IndexOf(sString2, 0, StringComparison.CurrentCulture) > -1)
    103. Else
    104. Return (sString1.IndexOf(sString2, 0, StringComparison.CurrentCultureIgnoreCase) > -1)
    105. End If
    106. End Function
    107. End Class


    Meine Funktion funktoniert super, halt nur nicht wenn Leerzeichen im Path sind (Shell *hust*), und der Path nicht in Anführungzeichen ist (Funktioniert: "C:\Program Files\App.exe" aber nicht: C:\Program Files\App.exe)


    ~MfG
    Hallo Timocop,

    Hast du' schon mit Regex probiert? Das Pattern könnte dann in etwa so aussehen:

    Quellcode

    1. ([A-Z]\:\/.*?\.[a-z]{1-3}\s)


    Grüsse

    Higlav

    Edit: sh** - funktioniert nur bei den oberen beiden - sry
    Willkommen im Forum. :thumbup:
    Wo kommt denn der String her?
    Die Kommandozeile kannst Du so zerpflücken:

    VB.NET-Quellcode

    1. Dim args() = Environment.GetCommandLineArgs
    2. For Each arg In args
    3. MessageBox.Show(arg)
    4. Next
    und wenn Du in sich geschlossene Pfade, die Leerzeichen enthalten, in "" übergibst, kommen sie sauber an, sonst nicht.
    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!
    @Timocop:

    RodFromGermany schrieb:

    Wo kommt denn der String her?
    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!
    Und warum sollten die jetzt großartig anders sein? Hast du ein Beispiel parat?
    „Was daraus gefolgert werden kann ist, dass jeder intelligentere User sein Geld lieber für Bier ausgibt, um einen schönen Rausch zu haben, und nicht dieses Ranzprodukt.“

    -Auszug aus einer Unterhaltung über das iPhone und dessen Vermarktung.

    ErfinderDesRades schrieb:

    beispiele scheinen in post#1 gegeben, und Higlav hat ja auch eine Vorlage gebastelt, die man nu noch weiterentwickeln müsste, denn Statt Laufwerks-Buchstaben können auch in %% eingeschlossene Schlüsselworte auftreten.
    Das lässt sich mit Regex auffinden - RegexTester
    Moin Radi,
    ich arbeite schon lange mit RegEx, ich wollte halt nur mal wissen ob es eine "einfachere" variante gibt als alles Manuell zu schreiben, da es unzählige Zeichen im Path vorkommen können.
    jo, da gibts ziemlich elegante Möglichkeiten, mit Regex Gruppen so zu definieren, dass dein Prob gelöst wird.
    Ich weiß daher nicht recht, was du mit "alles manuel schreiben" meinst. Das muss man ganz bestimmt nicht.

    Probier den Regextester mal aus, da ist auch eine Referenz der Syntax bei und viele Beispiele.

    ErfinderDesRades schrieb:

    jo, da gibts ziemlich elegante Möglichkeiten, mit Regex Gruppen so zu definieren, dass dein Prob gelöst wird.
    Ich weiß daher nicht recht, was du mit "alles manuel schreiben" meinst. Das muss man ganz bestimmt nicht.

    Probier den Regextester mal aus, da ist auch eine Referenz der Syntax bei und viele Beispiele.
    Nice, ich hab es doch noch hinbekommen. :D (mal gucken wie lang das hällt :rolleyes: )
    Mit "alles manuel schreiben" meinte ich dass es vieleicht in der Win API was gibt, wie halt "SearchPath", das man nicht wie mit RegEx alles rausfiltern muss.


    Naja wie auch immer, es funktioniert jetzt ...Noch :P


    Ich hab unterm Code nochmal zur sicherheit das dangehängt, funktioniert wunderbar:

    VB.NET-Quellcode

    1. For Each s As String In RegExMatchList(sPath, "([a-z]\:\\(.*?)\.(?:[-\w\.\d]+)*(?![\w\.]))", RegexOptions.IgnoreCase)
    2. s = SearchFile(s)
    3. If (String.IsNullOrEmpty(s) OrElse (Not IO.File.Exists(s))) Then Continue For
    4. Dim bAlreadyExist As Boolean = False
    5. For Each l As String In aList.ToArray
    6. If (StrEqual(l, s, False)) Then
    7. bAlreadyExist = True
    8. Exit For
    9. End If
    10. Next
    11. If (Not bAlreadyExist) Then
    12. aList.Add(s)
    13. End If
    14. Next

    Timocop schrieb:

    z.B von Autorun Einträgen etc.
    Fein.

    RodFromGermany schrieb:

    Wo kommt denn der String her?

    Und: Würdest Du bitte das Zitieren kompletter Posts sein lassen?
    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!
    @ErfinderDesRades

    Siehe Post 1# Quellcode mein lieber :rolleyes: :D
    Und ja, es funktioniert auch mit leerzeichen im Path. Wie C:\Dir\Dir Dir\App App.exe
    Solange [Driveletter] & [Extension] da sind, funktioniert alles :)

    VB.NET-Quellcode

    1. Function RegExMatchList(ByVal Text As String, ByVal Filter1 As String, ByVal Options As RegexOptions) As String()
    2. Dim aList As New List(Of String)
    3. For Each m As Match In Regex.Matches(Text, Filter1, Options)
    4. aList.Add(m.Value)
    5. Next
    6. Return aList.ToArray
    7. End Function
    eine Methode "ClearPath" gibts da garnet, nur eine Methode "CleanPath", und die returnt eine List(Of String), ich hab keine Idee, wie man RegexMatchlist() da "einfach vorher einsetzen" kann.

    Ich bastel mal eine Methode, die gibt alle DateiPfade aus genanntem Pattern zurück, als String().
    Das sollten nicht mehr als 15 Zeilen werden.
    nicht geschafft :( - es sind 20 Zeilen

    VB.NET-Quellcode

    1. Private _rgxCommandPathes As New Regex("(\s+|^)(?<Fullname>(%(?<SystemPath>.*?)%|(?<Drive>[^-]):|[^-])(?<RelativePath>.*?\.\S+))", RegexOptions.IgnoreCase)
    2. Private _KnownPathes As New Dictionary(Of String, String) From {{"SystemRoot", Environment.GetFolderPath(Environment.SpecialFolder.System)}, _
    3. {"WinDir", Environment.GetFolderPath(Environment.SpecialFolder.Windows)}}
    4. Private Function GetFullPathes(CommandArgs As String) As List(Of String)
    5. Dim r = New List(Of String)
    6. For Each match As Match In _rgxCommandPathes.Matches(CommandArgs)
    7. With match
    8. If .Groups("Drive").Success Then
    9. r.Add(.Groups("Fullname").Value())
    10. ElseIf .Groups("SystemPath").Success Then
    11. r.Add(_KnownPathes(.Groups("SystemPath").Value) & .Groups("RelativePath").Value)
    12. Else
    13. r.Add(Path.Combine(Environment.CurrentDirectory, .Groups("Fullname").Value))
    14. End If
    15. End With
    16. Next
    17. Return r
    18. End Function
    @ErfinderDesRades

    WOW, faszinierend! Du bist echt der RegEx König :thumbsup:

    Ich bin grade mal beim Basic zeugs von RegEx :D
    Aber der Pattern sieht auf ein paar blicken drauf, eigentlich recht einfach aus 8|

    Wie auch immer, herzlichen dank! Jetzt weiß ich auch wie man RegEx Gruppen erstellen kann! ^^

    Hab diese etwas modifiziert:

    VB.NET-Quellcode

    1. Private _rgxCommandPathes As New Regex("(\s+|^)(?<Fullname>(%(?<SystemPath>.*?)%|(?<Drive>[^-]):|[^-])(?<RelativePath>.*?\.\S+))", RegexOptions.IgnoreCase)
    2. Private Function GetFullPathes(ByVal CommandArgs As String) As String()
    3. Dim r As New List(Of String)
    4. For Each match As Match In _rgxCommandPathes.Matches(CommandArgs)
    5. With match
    6. If .Groups("Drive").Success Then
    7. r.Add(.Groups("Fullname").Value())
    8. ElseIf .Groups("SystemPath").Success Then
    9. r.Add(Environment.GetEnvironmentVariable(.Groups("SystemPath").Value) & .Groups("RelativePath").Value)
    10. Else
    11. r.Add(.Groups("Fullname").Value)
    12. End If
    13. End With
    14. Next
    15. Return r.ToArray
    16. End Function


    Werde diese dann mit SearchPath weiter anpassen.