Codierung der umgeleiteten Win Console-Befehlsausgabe steuern

1146
user3528651

Folgendes möchte ich tun:

Richtige Umleitung der Ausgabe von Konsolenanwendungen (ich verwende den Begriff Befehl in der restlichen Nachricht) in eine Datei mit 1252-Kodierung (um sie in der Standardkonfiguration von einem beliebigen Notepad-Soft aus lesbar zu machen.

Was ich beobachtet habe:

Chcp ist wirksam bei internen Befehlen und einigen externen Befehlen (den letzten)

Zunächst ist es erwähnenswert, dass CHCP unter Win7 und Win 10 unterschiedlich arbeitet.

Wenn der folgende Stapel von einer cmd-Eingabeaufforderung ausgeführt wird, können Sie feststellen, dass die Befehlsausgaben ordnungsgemäß in der win10-Konsole angezeigt werden, wohingegen eine win7-Konsole Zeichen aus ASCII-Zeichen schlecht darstellt.

for /f "tokens=2 delims=:" %%G in ('chcp') do Set _cp_=%%G chcp 1252 @echo test an internal command dir @echo test an external (recent) command: Robocopy robocopy .\ .\ /L @echo test an external (legacy) command: Xcopy xcopy test.txt 2>&1 chcp %_cp_% echo end of test.cmd batch  

Übrigens, ich bin daran interessiert zu wissen, was einen solchen Unterschied verursacht, obwohl es nicht wirklich der Zweck dieser Nachricht ist, und da sie durch Hinzufügen eines ps leicht zu beheben ist, rufen Sie „powershell [console] :: outputencoding = [system.text.encoding] :: getencoding auf (850) ”im Stapel nach dem 1. chcp-Befehl.

Was auch immer das eigentliche Problem ist, wenn die Stapelausgabe in eine Datei umgeleitet wird: test.cmd> test.txt.

In diesem Fall ist das Ergebnis dasselbe Betriebssystem. Die Ausgabe von internen Befehlen und neuen externen Befehlen (Robocopy, Bcdedit usw.) ist ordnungsgemäß 1252 kodiert. Ältere Befehle (xcopy, chcp usw.) sind nicht vorhanden (Ausgabe in OEM-Codeseite). Kurz gesagt, die meisten Befehle sind nicht von CHCP oder einer gleichwertigen Konsole betroffen.

Verschiedene Spekulationen über dieses Chaos:

  1. Der ältere Befehlscode basiert auf CRT, während interne und die neuesten externen Befehle die Win32-API verwenden. Es basiert auf dem letzten Abschnitt zur Entwicklung der Konsolenanwendung von MSDN Globalization Step-by-Step !

  2. Da zumindest win10, was in der Konsole angezeigt wird (gleiche Kodierung für alle Befehlsausgaben) und eine Datei gespeichert ist (Änderung der Ausgabecodierung je nach Befehl), können Ausgabe- / Eingabeströme je nach Art der behandelten Handles unterschiedlich behandelt werden. Konsolenfunktionen können für Anzeige- und E / A-Dateifunktionen bei Umleitung verwendet werden. Spekulation basierend auf High-Level-Konsolen-Eingabe- und -Ausgabefunktionen !

  3. MS empfiehlt, dass der Code von Konsolenanwendungen die OEM-Codierung des Ausgabestroms erzwingt. Ref. Konsolenanwendungsprobleme Wenn MS-Vorschlag im Code externer Befehle angewendet wird, kann dies erklären, warum die Umleitung ihrer Ausgabeströme in eine Datei immer OEM_CP codiert ist, unabhängig von der Konsolen-Codepage. Merkwürdig ist, sind ReadFile- und Write - Datei nicht unter genannten Funktionen durch folgende Faktoren beeinträchtigt SetFileApisToOEM

Schließlich weiß ich nicht, ob der Unterschied zwischen älteren Befehlen und den kürzlich eingeführten Befehlen darin besteht, dass der Code den Empfehlungen von MS entspricht und einfach, weil String-Literale im Vergleich zu OEM (OEM) und ANSI codiert sind.

Mögliche Lösungen / Problemumgehung

Wenn 3 richtig ist, gibt es sicherlich nur wenige. Es ist möglich, den Wert des Registrierungsschlüssels HKLM \ system \ currentset \ control \ NLS \ codepage OEMCP = 1252 zu ändern. Es ist nicht sicher (versuchen Sie nicht, Unicode 65001 einzustellen, Ihr System kann das Booten ablehnen) und unpraktisch (Neustart erforderlich). Oder füllen Sie die Datei nur mit OEM-kodiertem Inhalt und transcodieren Sie die Datei am Ende des Stapels mit dem PS-Skript. Einfach, aber nicht sehr elegant, wenn die Datei regelmäßig abgerufen und überprüft werden muss.

Wenn 2 korrekt ist, kann eine Funktion vorhanden sein, die die Codierung der E / A-Dateifunktion readfile und writefile steuert .

Wenn 1 richtig ist, sollte es möglich sein, die internationalen Einstellungen oder die Kultur der aktuellen Benutzersitzung und damit die Codepage der CRT-Anwendung zu steuern. Seit Win8 ist es möglich, über Powershell Internationale Einstellungen in Windows zu konfigurieren . Befehlszeilenanwendungen sind auch in der Lage, solche Dinge auszuführen . Wie auch immer, die Schwierigkeit besteht darin, eine „Kultur“ mit OEM-Codepage auf 1252 zu erstellen, da diese nicht in der vordefinierten Menge vorhanden ist .

Zögern Sie nicht, Ihr Wissen zu diesem Thema weiterzugeben, auch wenn es keine effektive Lösung für dieses Problem gibt. Ich bin nur neugierig zu verstehen, wie MS das implementiert hat.

2
Was hat 'bash' mit dieser Frage zu tun? Bitte entfernen Sie das Tag, wenn Sie es nicht erklären können. DavidPostill vor 8 Jahren 0
Ihr Testskript unter Windows 7 zeigt hier nichts Seltsames an. DavidPostill vor 8 Jahren 0
Sorry für das Bash-Tag, eigentlich nichts zu tun. Der Tag wurde mir vorgeschlagen und ich lese Batch. Wenn ich unter Windows 7 das Testskript ausführte, werden alle Nicht-Ascii-Zeichen schlecht dargestellt: Hier sind die ersten Befehle:> chcp 1252 Seite de codes active ** á **: 1252 test a internal command> dir Le Band im Lehrsaal C s ** Æ ** Appelle System Le num ** Ú ** ro de s ** Ú ** Volumen des Bandes xxx user3528651 vor 8 Jahren 0
Ah. Kann dir dann nicht helfen. Ich habe eine englische Version von Windows ohne lustige Zeichen;) DavidPostill vor 8 Jahren 0
: Egal, aber ja, ich habe vergessen zu erwähnen, dass das alles nur für Systeme außerhalb der Ländereinstellung von en-US (oder einem ähnlichen Gebiet) sinnvoll ist und Glyphen verwendet, die von ASCII-Zeichen in ihrer Landessprache abweichen user3528651 vor 8 Jahren 0
[Diese Frage und meine Antwort] (http://superuser.com/q/1056614/380318) sprechen mehr über die PowerShell-Änderung, auf die Sie hingewiesen haben, wenn andere daran interessiert sind. Ben N vor 8 Jahren 0

0 Antworten auf die Frage