Befehl rauscht durch, wenn keine MsgBox da ist

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von MemoAnMichSelbst.

    Befehl rauscht durch, wenn keine MsgBox da ist

    Hallo,

    ich habe ein Programm gebaut, welches Infos sammelt und dazu teils cmd-Befehle nutzt.
    Es hat alles sehr gut geklappt - bis ich meine Messageboxen, die Variablen zum debuggen für mich angezeigt haben, entfernt habe.
    Wenn ich über F8 mir alle Einzelschritte ansehe, klappt es auch. Also muss es wohl mit der Pause, die die Messagebox erzeugt, zu tun haben.
    Er schreibt den ipconfig auch weg- nur springt er dann raus aus der Sub in der er ist und ignoriert restliche Befehle- die form wird sofort aufgerufen.
    Was sollte ich dagegen tun ? Eine Wartezeit einbauen oder eher eine Schleife, die schaut, ob der Prozess läuft ?

    Der Befehl lautet

    VB.NET-Quellcode

    1. Shell("cmd /c ipconfig /all > %temp%\ipconfig.log")


    Ich habe hintendran mit System.Diagnostics.Process() eine if-Abfrage dran gebaut.
    Die wird aber auch ignoriert ;(
    Nimm mal die Process-Klasse, da hast Du die Möglichkeit, dem Programm explizit Zeit zu geben, um fertig zu starten:

    VB.NET-Quellcode

    1. Dim pr As New Process
    2. pr.StartInfo.FileName = "bla"
    3. pr.StartInfo.Arguments = "blabla"
    4. pr.Start()
    5. pr.WaitForInputIdle(1000)
    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!
    Hallo Rod,

    danke für deinen Tipp.
    Leider scheint das Übergeben der Argumente nicht zu funktionieren.

    Wenn ich tesweise an cmd veruche Argumente zu übergeben, geht cmd ohne Argumente auf und bleibt es auch.


    VB.NET-Quellcode

    1. Dim pr As New Process
    2. pr.StartInfo.FileName = "C:\Windows\System32\cmd.exe"
    3. pr.StartInfo.WorkingDirectory = "C:\Windows\System32"
    4. pr.StartInfo.Arguments = ("pause")
    5. pr.Start()
    6. pr.WaitForInputIdle(1000)
    7. MsgBox("pause")
    Soll die Buchstabenfolge "pause" angezeigt werden?
    Das geht nicht mit Arguments, da musste mal in der Process-Klasse nach InputStream, OutpuStream, ErrorStream suchen.
    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!

    Schalterschorsch schrieb:

    dass er ipconfig /all in eine TextDatei schreibt.
    Das geht so:
    ipconfig /all > yyy.txt

    -----------
    Ich merk gerade, dass das ganz so einfach nicht geht. :S
    -----------
    So geht es:

    VB.NET-Quellcode

    1. Process.Start("c:\Temp\xxx.bat")
    mit dieser Batch:
    c:\windows\system32\ipconfig /all > c:\Temp\yyyy.txt
    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 2 mal editiert, zuletzt von „RodFromGermany“ ()

    Hallo Rod,

    diese Bat-Idee war mir auch gekommen- wäre aber mein letzter Ausweg, da ich bei anderen Aufrufen noch Variablen übergeben müsste.
    Das würde dann heißen:

    - lasse vb.net eine Bat erstellen, welche laufen wird und schreibe die jedes mal neu, damit die Variable auch stimmt
    oder baue eine Variable als Schnittstelle zwischen beiden, damit die Bat nicht jedes mal neu erstellt werden muss

    Weil das mit meinen "debug-messageboxen" funktioniert hatte ich gehofft, dass man was auch immer die Messagebox tut
    so nachbauen kann, dass es klappt. Das ist mir mit Ruhepause und if ipconfig.exe has exited then ... nicht gelungen.
    Beim sfc zum Beispiel gelingt genau das - man kann sagen " Process.Start("C:\Windows\System32\sfc.exe", "/scannow")

    Vor allem würde ich gerne verstehen, weshalb derartiges passiert und vor allem weswegen plötzlich das Programm auf
    Durchzug stellt und andere Aufrufe nicht mehr macht. Die Aufrufe sind bei mir untereinander und es sollte danach eig. noch was laufen ...
    selbst wenn ich eine msgbox zwischen die beiden Sub-Aufrufe stelle, kommt diese nicht mehr 8o
    Edit: Vergiss das vorige Beispiel....

    Hier ein kleines Snippet zum weiterverwenden. :)

    VB.NET-Quellcode

    1. ''' <summary>
    2. ''' Startet ein Programm und schreibt den StandardOutput in eine Datei
    3. ''' </summary>
    4. ''' <param name="FileName">Pfad und Programmname des auszuführenden Programms</param>
    5. ''' <param name="OutputFilename">Pfad und Dateiname der zu schreibenden Datei</param>
    6. ''' <param name="AppendToFile">Soll der Output an die Datei angefügt werden? False überschreibt die Datei</param>
    7. ''' <param name="Arguments">Die gewünschten Programm Argumente</param>
    8. ''' <param name="WaitForExit">Soll die Funktion warten, bis das Programm beendet wurde?</param>
    9. ''' <param name="ExpectedExitCode">Welcher Exit-Code wird vom Programm erwartet, damit die Bedingung als erfüllt gilt</param>
    10. ''' <returns>Ein bool-Wert, der angibt ob der gewünschte Exit-Code erreicht wurde</returns>
    11. ''' <author></author>
    12. ''' <creationdate></creationdate>
    13. ''' <lasteditedby></lasteditedby>
    14. ''' <lasteditdate></lasteditdate>
    15. ''' <example>'Schreibt die Ausgabe von ipconfig in eine Datei im Anwendungsordner
    16. ''' Dim OutPath As String = IO.Path.Combine(Application.StartupPath, "ipconfig.txt")
    17. ''' If WriteOutputFromEXE("c:\windows\system32\ipconfig.exe", OutPath, False, "/all", True, 0) Then
    18. ''' Using sr As New IO.StreamReader(OutPath, System.Text.Encoding.Default)
    19. ''' MsgBox(sr.ReadToEnd)
    20. ''' End Using
    21. ''' End If</example>
    22. ''' <remarks></remarks>
    23. Public Function WriteOutputFromEXE(ByVal FileName As String, ByVal OutputFilename As String, Optional ByVal AppendToFile As Boolean = False, Optional ByVal Arguments As String = "", Optional ByVal WaitForExit As Boolean = True, Optional ExpectedExitCode As Integer = 0) As Boolean
    24. Using p As New Process
    25. p.StartInfo.FileName = FileName
    26. p.StartInfo.Arguments = Arguments
    27. p.StartInfo.RedirectStandardOutput = True
    28. p.StartInfo.UseShellExecute = False
    29. p.Start()
    30. Using sw As New IO.StreamWriter(OutputFilename, AppendToFile, System.Text.Encoding.Default)
    31. sw.Write(p.StandardOutput.ReadToEnd)
    32. End Using
    33. p.WaitForExit()
    34. If p.ExitCode = ExpectedExitCode Then
    35. Return True
    36. Else
    37. Return False
    38. End If
    39. End Using
    40. End Function
    41. Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    42. Dim OutPath As String = IO.Path.Combine(Application.StartupPath, "ipconfig.txt")
    43. If WriteOutputFromEXE("c:\windows\system32\ipconfig.exe", OutPath, False, "/all", True, 0) Then
    44. Using sr As New IO.StreamReader(OutPath, System.Text.Encoding.Default)
    45. MsgBox(sr.ReadToEnd)
    46. End Using
    47. End If
    48. End Sub
    SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

    Weil einfach, einfach zu einfach ist! :D

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

    vielen Dank für das Snippet !
    Hätte nie gedacht, dass mir sowas passieren kann wie "die Datei ist nicht existent" weil die Datei laut Prozess 2, der nicht wartet, noch nicht da ist.

    Ich habe gestern versucht mit Hilfe von dem Ausgabestream alles in ein Array zu schreiben und dieses dann in eine Txt umleiten zu lassen.
    Das klappt auch ohne diese File not found-exception, die man bekommt, weil die Exe noch nicht den file fertig geschrieben hat.
    Manko dabei:
    - ich muss das Array anfangs an seiner Größe schon definieren - obwohl ich nicht weiß wie viel rein kommt.
    Es kann einer Lan haben, Wlan, Vmware-Adapter- weiß der Kuckuk ...
    - wenn das array zu groß ist, stehen die Sachen mehrmals drin...
    Man kann ein Array im Nachhinein nach der Deklaration nochmal anpassen -aber mittendrin geht das nicht, oder ?

    Ich könnte natürlich auch den Ansatz nehmen alles wegzuschreiben und danach die Textdatei als Array einlesen und dann sagen: for i = 0 to TxtArray.length -1 lese Zeile für Zeile ein

    Vielen vielen Dank für eure Unterstützung - es ist mir echt eine große Hilfe :thumbsup:
    Es gibt zwar ne Möglichkeit, ein Array dynamisch zu vergrößern, aber dafür gibt es viel schönere Möglichkeiten.

    Nämlich eine List(of T) zu verwenden.

    VB.NET-Quellcode

    1. Private _MyList as new List(of String)
    2. Private Sub Main()
    3. _MyList.Add("Test1")
    4. MsgBox(_MyList.Count.ToString)
    5. _MyList.Add("Test2")
    6. MsgBox(_MyList.Count.ToString)
    7. End Sub


    Eine List(of T) ändert dynamisch ihre Größe.

    btw: Du kannst alles, was du über ipconfig bekommst, auch über .NET auslesen.

    VB.NET-Quellcode

    1. Dim IPAdresses As New System.Text.StringBuilder()
    2. Dim AllInterfaces As New System.Text.StringBuilder
    3. Dim snm As String = String.Empty
    4. 'Alle Interfaces durchlaufen
    5. For Each iface As System.Net.NetworkInformation.NetworkInterface In System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces
    6. 'Wenn dem Interface eine oder mehrere Adresse zugewiesen ist
    7. If iface.GetIPProperties.UnicastAddresses().Count > 0 Then
    8. 'Schreibe alle Adressen in einen StringBuilder
    9. For i As Integer = 0 To iface.GetIPProperties.UnicastAddresses.Count - 1
    10. 'Loopback-Interfaces haben keine Subnet Mask
    11. If Not System.Net.IPAddress.IsLoopback(iface.GetIPProperties.UnicastAddresses(0).Address) Then
    12. snm = iface.GetIPProperties.UnicastAddresses(i).IPv4Mask.ToString()
    13. Else
    14. snm = "{nothing}"
    15. End If
    16. 'IP und Adresse zum StringBuilder hinzufügen
    17. IPAdresses.AppendLine(iface.GetIPProperties.UnicastAddresses(i).Address.ToString() & vbTab & snm)
    18. Next
    19. End If
    20. 'Informationen im StringBuilder "AllInterfaces" zusammenführen
    21. AllInterfaces.AppendLine(String.Format("Name: {1}{0}MAC: {2}{0}Adresse(n):{0}{3}", vbCrLf, iface.Name, iface.GetPhysicalAddress, IPAdresses.ToString))
    22. AllInterfaces.AppendLine()
    23. 'StringBuilder leeren
    24. IPAdresses.Remove(0, IPAdresses.Length)
    25. Next
    26. 'Infos ausgeben
    27. MsgBox(AllInterfaces.ToString)


    Damit sparst du dir den Extra-Aufruf von ipconfig und das parsen der Text-Datei.
    SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

    Weil einfach, einfach zu einfach ist! :D
    Hi,

    mal ne andere Frage:
    Machst du das alles im Form Load?
    Es gibt da nen Bug dass er dort keine Fehlermeldungen wirft sondern die Sub einfach beendet (glaub unter Windows 7).
    Hierfür bediene ich mich zur Fehlermeldungssuche eines Try Catches... Da ja leider die Windows-Fehlermeldung dort nicht funktioniert. Schau doch mal ob er bei nem Try Catch ne Fehlermeldung raus haut...
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D