Umlaute an Prozess über StandardInput senden funktioniert nicht -> StandardInputEncoding?

  • VB.NET

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

    Umlaute an Prozess über StandardInput senden funktioniert nicht -> StandardInputEncoding?

    Hallo!

    Ich hab die cmd.exe als Prozess gestartet und alle Standardströme umgeleitet.
    Der Projektordner heisst (absichtlich mit Umlaut) "Täst"
    Alles was über StandardOutput daherkommt lass ich mir in einer mehrzeiligen Textbox anzeigen.
    Nach dem Start des cmd-Prozesses steht dort:

    Microsoft Windows [Version 6.1.7601]
    Copyright (c) 2009 Microsoft Corporation. Alle Rechte vorbehalten.
    C:\Users\Admin\documents\visual studio 2010\Projects\T„st\T„st\bin\Debug>

    Die Umlaute werden also falsch eingelesen.
    Über cmd.StandardInput.WriteLine sende ich jetzt ein "cd\". Das funktioniert.

    Wenn ich jetzt wieder in den Ordner mit Umlauten wechseln will mit

    VB.NET-Quellcode

    1. cmd.StandardInput.WriteLine("cd " & Chr(34) & "C:\Users\Admin\documents\visual studio 2010\Projects\Täst\Täst\bin\Debug" & Chr(34))

    bekomme ich folgendes über StandardOutput:

    C:\>cd "C:\Users\Admin\documents\visual studio 2010\Projects\Täst\Täst\bin\Debug"

    ABER: Über StandardError bekomme ich "Das System kann den angegebenen Pfad nicht finden."

    Das Encoding für StandardOutput lässt sich ja ändern mit

    VB.NET-Quellcode

    1. cmd.StartInfo.StandardOutputEncoding = System.Text.Encoding.GetEncoding(437)

    Damit wird dann alles aus StandardOut auch richtig wiedergegeben:

    Microsoft Windows [Version 6.1.7601]
    Copyright (c) 2009 Microsoft Corporation. Alle Rechte vorbehalten.
    C:\Users\Admin\documents\visual studio 2010\Projects\Täst\Täst\bin\Debug>

    ABER: Wie ändere ich das Encoding für StandardInput? StartInfo.StandardInputEncoding gibt es ja (aus mir unersichtlichen Gründen) nicht.
    Poste bitte mal den gesamten Code, da lässt sich Dein Effekt leichter nachvollziehen.
    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!
    Ja klar, Sorry!

    VB.NET-Quellcode

    1. Public Delegate Sub Sub_Delegate_String(ByVal s As String)
    2. Public Class Form1
    3. Dim cmd As Process = Nothing
    4. Dim del As Sub_Delegate_String
    5. Dim command As String
    6. Dim sw As System.IO.StreamWriter = Nothing
    7. Dim encoding = System.Text.Encoding.GetEncoding(437)
    8. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    9. cmd = New Process()
    10. cmd.StartInfo.ErrorDialog = True
    11. cmd.StartInfo.UseShellExecute = False
    12. cmd.StartInfo.RedirectStandardInput = True
    13. cmd.StartInfo.RedirectStandardOutput = True
    14. cmd.StartInfo.RedirectStandardError = True
    15. cmd.StartInfo.FileName = "cmd.exe"
    16. cmd.StartInfo.CreateNoWindow = True
    17. cmd.StartInfo.StandardOutputEncoding = System.Text.Encoding.GetEncoding(437)
    18. AddHandler cmd.OutputDataReceived, AddressOf cmdHandler
    19. cmd.Start()
    20. cmd.BeginOutputReadLine()
    21. cmd.StandardInput.Write("cd" & vbNewLine)
    22. cmd.StandardInput.Write("cd " & Chr(34) & "C:\Users\Admin\documents\visual studio 2010\Projects\Täst\Täst\bin\Debug" & Chr(34) & vbNewLine)
    23. MsgBox(cmd.StandardError.ReadLine)
    24. cmd.StandardInput.Write("cd" & vbNewLine)
    25. End Sub
    26. Private Sub cmdHandler(ByVal sendingProcess As Object, ByVal outLine As DataReceivedEventArgs)
    27. If Not String.IsNullOrEmpty(outLine.Data) Then
    28. del = AddressOf Append_Textbox1
    29. Me.Invoke(del, outLine.Data)
    30. End If
    31. End Sub
    32. Public Sub Append_Textbox1(ByVal s As String)
    33. TextBox1.AppendText(vbNewLine & s)
    34. End Sub
    35. Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
    36. Try
    37. cmd.StandardInput.Flush()
    38. cmd.StandardInput.Close()
    39. cmd.CancelOutputRead()
    40. cmd.Close()
    41. Catch
    42. End Try
    43. End Sub
    44. End Class


    PS: Wieseo werden die Backslashes in den Zeilen cmd.StandardInput.Write("cd\" & vbNewLine) oberhalb in der Code-Ansicht nicht angezeigt?

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

    Iwo fehlt da noch das Input-Encoding, hab aber momentan keine Zeit:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Text
    2. Public Class Form1
    3. Private WithEvents cmd As Process = New Process()
    4. 'Private command As String
    5. Private sw As System.IO.StreamWriter = Nothing
    6. Private myEncoding As Encoding = System.Text.Encoding.Default 'GetEncoding(437)
    7. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    8. cmd.StartInfo.ErrorDialog = True
    9. cmd.StartInfo.UseShellExecute = False
    10. cmd.StartInfo.RedirectStandardInput = True
    11. cmd.StartInfo.RedirectStandardOutput = True
    12. cmd.StartInfo.RedirectStandardError = True
    13. cmd.StartInfo.FileName = "cmd.exe"
    14. cmd.StartInfo.CreateNoWindow = True
    15. cmd.StartInfo.StandardOutputEncoding = myEncoding 'System.Text.Encoding.GetEncoding(437)
    16. cmd.Start()
    17. sw = cmd.StandardInput
    18. Dim myEnc = cmd.StandardInput.Encoding
    19. cmd.BeginOutputReadLine()
    20. 'cmd.StandardInput.Write("cd" & Environment.NewLine)
    21. cmd.StandardInput.Write("cd C:\Temp\Täst" & Environment.NewLine)
    22. MsgBox(cmd.StandardError.ReadLine)
    23. 'cmd.StandardInput.Write("cd" & Environment.NewLine)
    24. End Sub
    25. Private Sub cmdHandler(ByVal sendingProcess As Object, ByVal outLine As DataReceivedEventArgs) Handles cmd.OutputDataReceived
    26. If Not String.IsNullOrEmpty(outLine.Data) Then
    27. Me.Invoke(Sub() Me.TextBox1.AppendText(Environment.NewLine & outLine.Data))
    28. End If
    29. End Sub
    30. Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
    31. Try
    32. If cmd IsNot Nothing Then
    33. cmd.StandardInput.Flush()
    34. cmd.StandardInput.Close()
    35. cmd.CancelOutputRead()
    36. cmd.Close()
    37. End If
    38. Catch
    39. End Try
    40. End Sub
    41. End Class
    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!
    @Eierlein: Sehr geile Idee, schade dass es nicht funktioniert (Es werden wirklich zwei Beistriche übertragen und leider kein ä daraus).

    @RodFromGermany: Das mit dem Umweg über einen StremWriter hab ich auch schon wo gelesen, aber ich hab immer noch keine Möglichkeit gefunden das Encoding eines StreamWriters zu ändern.

    VB.NET-Quellcode

    1. System.IO.Streamwriter
    hat zwar ein Attribut namens Encoding, das is aber nur ReadOnly.
    Man kann angeblich dem Konstruktor vom StreamWriter ein Encoding übergeben. Leider funktioniert das bei mir nicht:

    VB.NET-Quellcode

    1. Dim encoding = System.Text.Encoding.GetEncoding(437)
    2. Dim sw As New System.IO.StreamWriter(cmd.StandardInput, encoding)

    liefert
    Fehler 1 Fehler bei der Überladungsauflösung, da keine zugreifbare "New" mit diesen Argumenten aufgerufen werden kann:
    "Public Sub New(path As String, append As Boolean)": Der Wert vom Typ "System.IO.StreamWriter" kann nicht in "String" konvertiert werden.
    "Public Sub New(stream As System.IO.Stream, encoding As System.Text.Encoding)": Der Wert vom Typ "System.IO.StreamWriter" kann nicht in "System.IO.Stream" konvertiert werden.

    Wie könnte es sonst gehen?

    Tintifax schrieb:

    Wie könnte es sonst gehen?
    Probier es mal so:

    VB.NET-Quellcode

    1. Dim sw As New System.IO.StreamWriter(cmd.StandardInput.BaseStream, encoding)
    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!