2010-05-18 9 views
14

Ich habe ein Problem mit der Codierung von process.standartInput Codierung. Ich verwende einen Prozess in meiner Windows-Formularanwendung, aber die Eingabe sollte UTF-8 sein. Process.StandardInput.Encoding ist nur lesbar, so dass ich es nicht auf UTF-8 setzen kann und es Windows-Standardcodierung erhält, die native Zeichen verschlechtert, die in UTF-8 gut sind. Im Programm werden 2 Prozesse verwendet, die Ausgabe in eine Datei schreiben und andere Lesevorgänge. Da ich Ausgabekodierung zu UTF-8 einrichten kann, dass Teil richtig funktioniert, aber das Zurücklesen ist der Teil, in dem ich Probleme habe. Ich werde den Teil einschließen, in dem ich den Prozess verwende.process.standardInput Codierung Problem

ProcessStartInfo info = new ProcessStartInfo("mysql"); 
info.RedirectStandardInput = true; 
info.RedirectStandardOutput = false; 
info.Arguments = mysqldumpstring; 
info.UseShellExecute = false; 
info.CreateNoWindow = true; 
Process p1 = new Process(); 
p1.StartInfo = info; 
p1.Start(); 
string res = file.ReadToEnd(); 
file.Close(); 
MessageBox.Show(p1.StandardInput.Encoding.EncodingName); //= where encoding should be Encoding.UTF8; 
p1.StandardInput.WriteLine(res); 
p1.Close(); 

Antwort

1

habe es funktioniert jetzt setzen meine Anwendung Ausgabetyp zu Konsole Anwendung und verwaltet, um das Konsolenfenster zu verstecken erscheint vor den Formularen. Es funktioniert im Grunde wie normal, nur wenn das Programm läuft, ein Konsolenfenster erscheint und versteckt sich.

static class Program 
{ 
    [DllImport("kernel32.dll")] 
    static extern bool AttachConsole(int dwProcessId); 
    private const int ATTACH_PARENT_PROCESS = -1; 

    [DllImport("kernel32.dll", SetLastError = true)] 
    public static extern bool SetConsoleCP(
     uint wCodePageID 
     ); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    public static extern uint GetConsoleCP(); 

    [DllImport("user32.dll")] 
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 

    [DllImport("user32.dll")] 
    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 

    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Console.Title = "Stok"; 
     // redirect console output to parent process; 
     // must be before any calls to Console.WriteLine() 
     AttachConsole(ATTACH_PARENT_PROCESS); 
     System.Console.InputEncoding = Encoding.UTF8; 

     IntPtr hWnd = FindWindow(null, "Stok"); //put your console window caption here 

     if (hWnd != IntPtr.Zero) 
     { 
      //Hide the window 
      ShowWindow(hWnd, 0); // 0 = SW_HIDE 
     } 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
    } 
} 
20

von Stream Mit dem nächsten Weg erstellt (statt StandardInput) ergibt gewünschtes Ergebnis:

StreamWriter utf8Writer = new StreamWriter(proc.StandardInput.BaseStream, Encoding.UTF8); 
utf8Writer.Write(...); 
utf8Writer.Close(); 
+1

Danke. Löst das Problem gut. Beachten Sie, dass dies auch für StandardOutput funktioniert. –

+0

Leider scheint dies nicht mehr zu funktionieren - eine UTF16 (!) BOM (FF FE) steht noch vor den Daten. Nick's Workaround scheint die einzige, hässliche Lösung für den Moment zu sein. – MvanGeest

+0

Siehe Antwort von Brendon unten ... –

4

Eine andere Lösung ist die Konsole Inputencoding zu setzen, bevor Sie den Prozess erstellen.

Console.InputEncoding = Encoding.UTF8; 
4

Ich habe gerade dieses Problem festgestellt und konnte die Console.InputEncoding Technik verwenden, da es nur in Konsolenanwendungen zu funktionieren scheint.

Aus diesem Grund versuchte ich Victors Antwort, aber ich stieß auf das gleiche Problem wie der Kommentator MvanGeest, wo durch die BOM noch hinzugefügt wurde. Nach einiger Zeit stellte ich fest, dass es möglich ist, eine neue Instanz von UTF8Encoding zu erstellen, bei der die BOM deaktiviert ist. Dadurch wird verhindert, dass die BOM geschrieben wird. Hier ist eine modifizierte Version von Victors Beispiel, die die Änderung zeigt.

StreamWriter utf8Writer = new StreamWriter(proc.StandardInput.BaseStream, new UTF8Encoding(false)); 
utf8Writer.Write(...); 
utf8Writer.Close(); 

Hoffe das spart jemand einige Zeit.