Befehlszeilenargumente auslesen und verarbeiten

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von NoIde.

    Befehlszeilenargumente auslesen und verarbeiten

    Hallo,

    ich stehe gerade etwas auf dem Schlauch und suche etwas Hilfe. Ich würde gerne von einem Steam Spiel den Startparameter einlesen wollen.
    Z.B: server.exe -startport 27015 -startip 127.0.0.1
    Ich würde gerne die Werte der Variablen auslesen können und verändern können. Habe es mit My.Application.CommandLineArgs versucht und alle in eine Variable gespeichert und anschließend mit String.Contains geprüft ob "Startport" vorhanden ist, aber komme dann nicht auf den Wert. Weiß auch nicht ob diese Lösung elegant ist.

    Würde mich über Positive Antworten freuen :)
    Du willst die Startparameter deiner eigenen Anwendung auslesen? Ein Stichwort um dich auf den rechten Weg zu bringen:

    REGEX
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Du möchtest von einem Steam-Spiel die Startargumente auslesen und versuchst das mit My.Application.CommandLineArgs? Bin gerade ein wenig verwirrt. Ist das denn dein Spiel?(Bist du denn der Inhaber)

    Wenn Steam nicht dein Programm startet, sind in deinem Programm auch nicht diese Argumente drin. Hast du vllt. die Original exe mit deiner vertauscht?

    Wenn du nun von einem anderen Programm die Argumente haben willst, kannst du das mit WMI machen, mittels WinAPi geht's auch, glaube mit NtQueryInformationProcess. Am einfachsten wird sein die Windowsinterne WMIC.exe zu starten und den Output zu redirecten.

    VB.NET-Quellcode

    1. Dim p As New Process
    2. With p.StartInfo
    3. .FileName = "wmic.exe"
    4. .Arguments = "process where ""name='cmd.exe'"" get commandline"
    5. .RedirectStandardInput = True
    6. .RedirectStandardOutput = True
    7. .RedirectStandardError = True
    8. .UseShellExecute = False
    9. .CreateNoWindow = True
    10. End With
    11. p.Start()
    12. Dim x As String = p.StandardOutput.ReadToEnd()
    13. MessageBox.Show(x)


    Wenn es nicht klappt, kann ich mir vorstellen, das Daten mit Steam und dem Spiel durch die steam_api.dll(habe ich bei jedem Steam Spiel im Ordner) getauscht werden, dann kommst du wohl nur durch einen Debugger da dran(OllyDbg z.B.).
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „NoIde“ ()

    @mrMo Etwas übertrieben. Meinste nich?
    @Marcello Zieh ne ListBox auf das GUI und fang an mit:

    VB.NET-Quellcode

    1. ListBox1.Items.AddRange(Environment.GetCommandlineArgs())
    In den Zeilen steht dann:
    • Pfad Deines Programms
    • -startport
    • 27015
    • -startip
    • 127.0.0.1
    Teste Element mit Index 1|3 auf "-startport", "-startip",
    das Port bekommst Du mit Integer.Parse(mm),
    die IP-Adrersse mit IpAddress.TryParse(nn).
    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!
    Guten Morgen an euch alle,

    bin erstmal arbeiten, werde das später mal testen :)
    @Nolde Nein, ich bekomme über die Startparameter ( zb Port etc.) die Werte an mein Programm und mit diesem würde ich die Werte bearbeiten/verarbeiten wollen und damit die Server.exe starten. Sorry falls es im ersten Post schlecht formuliert worden ist. Das ganze wollte ich als Konsolenanwendung machen.

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

    @RodFromGermany - Mit

    VB.NET-Quellcode

    1. Integer.Parse(mm)

    VB.NET-Quellcode

    1. IpAddress.TryParse(nn)
    hole ich doch aus den String von ListBox1.Items.AddRange(Environment.GetCommandlineArgs()) rein nur die Ports und Ip's raus. Das ist aber nicht die Lösung für mein Problem :) Das ist z.b. sowas bekomme ich als Parameter rein

    Quellcode

    1. -serverip xxx.xxx.xxx.xxx -serversteamport 8766 -servergameport 27015 -serverqueryport 27016 -servername MyGame -serverplayers 8 -difficulty Normal -inittype Continue -slot 1


    Hatte ich vorher nicht ganz genau gesagt. Wäre es nur für Ports und IP's wäre es sicherlich eine elegante Lösung :)
    Fazit: bin immer noch auf der Suche. Also muss ich doch auf Regex zurück greifen? :)
    Das ist dann wohl doch ein Fall für Regex. du brauchst alles was zwischen 2 - ist, Ausnahme "Slot 1" da brauchst du ja vom - bis zum Zeilenende.

    VB.NET-Quellcode

    1. Dim args As String = "-serverip xxx.xxx.xxx.xxx -serversteamport 8766 -servergameport 27015 -serverqueryport 27016 -servername MyGame -serverplayers 8 -difficulty Normal -inittype Continue -slot 1"
    2. Dim regex As New Regex("(?<=-)(.*?)(?=(-)|($))")
    3. Dim matchcollection As MatchCollection = regex.Matches(args)
    4. For Each match In matchcollection
    5. MessageBox.Show(match.ToString())
    6. Next


    Für alle Fälle:
    RegEx Tutorial - Blutige Anfänger und Fortgeschrittene
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

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

    *unnötiges Zitat entfernt*

    Vielen Dank :) Ich lese gleich nochmal das Tutorial hinterher, weil ich wissen möchte, was das bringt :

    VB.NET-Quellcode

    1. Dim regex As New Regex("(?<=-)(.*?)(?=(-)|($))")
    Müsste dann noch mit RegEx schaue, wie ich nur an die Werte komme. Also d.h. Ich mache einen String z.b. Port und dort lasse ich dann halt 8766 abspreichern :)

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

    Ich habe gerade noch mal da rein geschaut, mein Pattern wirst du nicht mit dem was auf der Seite ist erklären können. Ich zeige dir erstmal die "Rohform" des Patterns Edit: War ja doch zu finden, aber erst auf Seite 2 :S )

    Quellcode

    1. (?<=)(.*?)(?=)

    3 Klammern, was in der 1. Klammer hinter dem = steht, steht auch im gesuchten, soll aber nicht im Match sein. In der mittleren Klammer ist das was im Match sein soll, .*? kann ja alles mögliche sein, was nun aber hinter dem = in der 3. Klammer steht, kommt auch im Text vor, nachdem teil den du haben willst, ist aber ebenfalls nicht im Match. Kurz gesagt, so findet man dann alles was zwischen 2 Zeichenketten ist.

    Der Pattern für die ServerIp wäre dann

    VB.NET-Quellcode

    1. Dim regex As New Regex("(?<=-serverip\s)(.*?)(?=(\s-))")


    Den Rest kannst du mit dem Tutorial erkunden. ;)

    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

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

    Auch wenn's total Off-Topic ist:
    @NoIde, Ich find's immer wieder interessant, dass Dein Name falsch geschrieben wird. 8o
    @all: Der Benutzername wird NOIDE - Mit einem I wie Informatik geschrieben. Nicht mit einem L!
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed Vielleicht sollte ich den I-Punkt beim Avatar mit roten Pfeilen und blauen Fog-Glow hervorheben. :D Finds mittlerweile sogar Amüsant, kann mir vorstellen, wenn einer mich mit der @-Funktion(nenns ichs mal) nicht findet der schaut erstmal komisch. Die Reagiert ja erst nach dem 3. Zeichen(nach @). Schliesst auch wieder beim löschen des 3. Zeichens.


    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „NoIde“ ()

    Das ganze wollte ich als Konsolenanwendung machen.

    Bei einer Consolen Anwendung bekommst du die Startargumente doch bereits als String Array, da benötigst du kein RegEx.


    Beispiel auflisten der Startargumente:

    C#-Quellcode

    1. if (args != null && args.Length >= 2) {
    2. for (int i = 1; i < args.Length; i += 2)
    3. Console.WriteLine("\n Name: {0}\n Command: {1}", args[i - 1], args[i]);
    4. Console.ReadKey();
    5. }

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

    @Fakiz

    Moin, du hast recht :) Bei C# hat man ja auch direkt den String als Array. Doch ich finde diese Lösung etwas „unsauber/unelegant“ gelöst.
    Grund: Wird der Benutzer eine andere reihenfolge der Startparameter nutzen / oder andere Parameter nutzen - würde zb ein weiterer festgelegter Schritt nicht möglich sein. Müsste ja dann vorher jeden Wert des Arrays abfragen, was enthalten ist, oder habe ich gerade ein Denkfehler? :)
    Du müsstest wenn mit Regex jedes Pattern auf jeden Eintrag im Array anwenden, oder mit den String-Funktionen(Contains, Split ect...) auch jeden Eintrag bearbeiten. Oder auch zu einen String verketten und verarbeiten. Da find ich das so einfacher.

    Marcello schrieb:

    Bei C# hat man ja auch direkt den String als Array


    VB.NET-Quellcode

    1. Dim args() As String = Environment.GetCommandLineArgs

    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

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

    NoIde schrieb:

    Du müsstest wenn mit Regex jedes Pattern auf jeden Eintrag im Array anwenden


    kann man nicht einfach Pattern Gruppen machen? ( -serverip | -serverport ) ?
    Ich würde vermutlich dieses Pattern verwenden: (?:-([^ ]*) ([^ ]*))
    Es setzt nicht auf Lookbehinds und ist glaube ich etwas einfacher zu verstehen.
    Am Ende einfach durch alle Matches iterieren und aus Gruppe 1 den Parameter, aus Gruppe 2 den Wert lesen.