Garantierte Lokalisierung / Russifizierung der Windows-Konsole

Einführung

Konsolenanwendungen sind nach wie vor die beliebteste Art von Anwendungen. Die meisten Entwickler haben ihre Architektur und Geschäftslogik in der Konsole verbessert. Gleichzeitig sind sie häufig mit dem Problem der Lokalisierung konfrontiert - der russische Text, der sich in der Quelldatei in angemessener Weise widerspiegelt, wenn er auf der Konsole angezeigt wird, hat die Form des sogenannten. "krakozyabr".





Im Allgemeinen ist es nicht schwierig, die Windows-Konsole mit dem entsprechenden Sprachpaket zu lokalisieren. Dennoch wurde im Wesentlichen noch keine vollständige und eindeutige Lösung für dieses Problem gefunden. Der Grund dafür liegt hauptsächlich in der Natur der Konsole, die als Systemkomponente der statischen Klasse System.Console ihre Methoden der Anwendung über System-Shell-Programme wie die Befehlszeile oder den Befehlsprozessor (cmd) zur Verfügung stellt. exe), PowerShell, Terminal und andere.

Tatsächlich steht die Konsole unter doppelter Kontrolle - Anwendungen und Shells, was eine potenzielle Konfliktsituation darstellt, vor allem im Hinblick auf die Verwendung von Codierungen.





Dieses Material bietet keinen strengen Aktionsalgorithmus, sondern zielt darauf ab, die Hauptprobleme zu beschreiben, auf die der Entwickler einer lokalisierten Konsolenanwendung unweigerlich stößt, sowie einige Möglichkeiten, diese zu lösen. Es wird davon ausgegangen, dass der Entwickler auf diese Weise eine Strategie für die Arbeit mit einer lokalisierten Konsole entwickeln und vorhandene technische Funktionen effektiv implementieren kann, von denen die meisten gut beschrieben sind und hier weggelassen werden.





Arten von Konsolen

Im Allgemeinen lauten die Konsolenfunktionen wie folgt:





  • Verwaltung des Betriebssystems und der Systemumgebung von Anwendungen auf der Grundlage der Verwendung von Standard-Eingabe- / Ausgabegeräten des Systems (Bildschirm und Tastatur) unter Verwendung der Befehle des Betriebssystems und / oder der Konsole selbst;





  • - , -.





Windows - (CMD). PowerShell (PS), Windows PowerShell (WPS) Terminal. Windows Windows Power Shell 5, - 7-, (, 6-) - . Terminal - , PowerShell .





Visual Studio (CMD-D).





, Windows, " " . , - DOS (CP437, CP866) Windows Unicode.





: / (habr.com)





Windows CP1251 (Windows-1251, ANSI, Windows-Cyr), 8- CP65001 (UTF-8, Unicode Transformation Format), , . , , Windows DOS - CP437 (DOSLatinUS, OEM) CP866 (AltDOS, OEM).





1. ( , .) UTF-8. , .





2. , Notepad++. Visual Studio , VS.





, " ", 1 2, :





- CMD, PS WPS. CHCP, Echo c (. 1), , UTF-8 (CP65001): , , , .





:





  • > Echo ffffff //





  • PS> Echo ffffff // PowerShell





  • PS> Echo ffffff ?????? // Windows PowerShell





:





using System;
using ova.common.logging.LogConsole;
using Microsoft.Extensions.Logging;
using ova.common.logging.LogConsole.Colors;

namespace LoggingConsole.Test
{
    partial class Program
    {
        static void Main2(string[] args)
        {
            ColorLevels.ColorsDictionaryCreate();
            Console.WriteLine("Hello World! , !");     //     
            LogConsole.Write("   ", LogLevel.Information);
            Console.WriteLine($"8. Active codepage: input {Console.InputEncoding.CodePage}, output {Console.OutputEncoding.CodePage}");
            Console.ReadKey();
        } 
    }
}
      
      



, : WPS .





Tab.  1. Das Ergebnis des Konsolenbefehls Echo ffffff ffffff
. 1. Echo ffffff

50% , .2.





Tab.  2. Ergebnis der Ausführung der Anwendung LoggingConsole.Test
. 2. LoggingConsole.Test

o 3. PowerShell . , ...





Windows DOS. CP437, CP866. cmd.exe 866, 437, .





4. CHCP - 866, 1251, 65001.





5. . : \HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor Autorun : chcp < >. : Windows UTF-8 (qastack.ru), : Change default code page of Windows console to UTF-8.





Visual Studio

Visual Studio , Windows PowerShell . , , . - Windows, , , .





Visual Studio , Visual Studio , , , . , Windows , CHCP, . , , , 437 866.





6. , .





- ? - ".exe" , . , , , - - ,





Visual Studio

- , , , .





, - . Microsoft : "Programs that you start after you assign a new code page use the new code page. However, programs (except Cmd.exe) that you started before assigning the new code page will continue to use the original code page". , , , . - ?





! - , - -.





, . Write , , , , , . , .





F:\LoggingConsole.Test\bin\Release\net5.0>chcp
Active code page: 1251

F:\LoggingConsole.Test\bin\Release\net5.0>loggingconsole.test
Codepages: current 1251:1251, setted 437:437, ΓΓεΣΦ∞ 5 ±Φ∞ΓεδεΓ ∩ε-≡≤±±ΩΦ: Θ÷≤Ωσ=Θ÷≤Ωσ
Codepages: current 437:437, setted 65001:65001,  5  -: =
Codepages: current 65001:65001, setted 1252:1252, ââîäèì 5 ñèìâîëîâ ïî-ðóññêè: éöóêå=éöóêå
Codepages: current 1252:1252, setted 1251:1251,  5  -: =
Codepages: current 1251:1251, setted 866:866,  5  -є: Ўє=Ўє
Codepages: current 866:866, setted 1251:1251,  5  -: =
Codepages: current 1251:1251, setted 1252:1252, ââîäèì 5 ñèìâîëîâ ïî-ðóññêè: éöóêå=éöóêå

F:\LoggingConsole.Test\bin\Release\net5.0>chcp
Active code page: 1252
      
      



  • 1251 ( 2);





  • (current, setted);





  • 1252 ( 11, setted);





  • ( 14 - Active codepage 1252);





  • (setted 1251:1251) ( 8 10).





using System;
using System.Runtime.InteropServices;

namespace LoggingConsole.Test
{
    partial class Program
    {
        [DllImport("kernel32.dll")] static extern uint GetConsoleCP();
        [DllImport("kernel32.dll")] static extern bool SetConsoleCP(uint pagenum);
        [DllImport("kernel32.dll")] static extern uint GetConsoleOutputCP();
        [DllImport("kernel32.dll")] static extern bool SetConsoleOutputCP(uint pagenum);
        
        static void Main(string[] args)
        {
            Write(437);
            Write(65001);
            Write(1252);
            Write(1251);
            Write(866);
            Write(1251);
            Write(1252);
         }

        static internal void Write(uint WantedIn, uint WantedOut)
        {
            uint CurrentIn = GetConsoleCP();
            uint CurrentOut = GetConsoleOutputCP();
            Console.Write($"current {CurrentIn}:{CurrentOut} -  , "); /*wanted {WantedIn}:{WantedOut},*/
            SetConsoleCP(WantedIn);
            SetConsoleOutputCP(WantedOut);
            Console.Write($"setted {GetConsoleCP()}:{GetConsoleOutputCP()} -  , ");
            Console.Write($" 3  -: ");
            string str = "" + Console.ReadKey().KeyChar.ToString();
            str += Console.ReadKey().KeyChar.ToString();
            str += Console.ReadKey().KeyChar.ToString();
            Console.WriteLine($"={str}");
        }
      
        static internal void Write(uint ChangeTo)
        {
            Write(ChangeTo, ChangeTo);
        }
    }
}

      
      



- . .Net , WinAPI: SetConsoleCP(uint numcp) SetConsoleOutputCP(uint numcp), numcp - . : Console Functions - Windows Console | Microsoft Docs. WInAPI .





7. ! SetConsoleCP - .





  1. PowerShell ( ), Windows PowerShell;





  2. Stellen Sie die Standard-Konsolencodepage auf CP65001 (utf-8 Unicode) oder CP1251 (Windows-1251-Cyr) ein, siehe Tipp 5 ;





  3. Entwickeln Sie Anwendungen in der utf-8-Unicode-Codierung.





  4. Steuern Sie die Codierung von Quellcodedateien, Textdatendateien, z. B. mit Notepad ++.





  5. Implementieren Sie die programmatische Verwaltung der Anwendungslokalisierung in der Konsole, Beispiel unten unter dem Schnitt:





Ein Beispiel für das programmgesteuerte Festlegen der Codepage und das Lokalisieren der Anwendung in der Konsole
using System;
using System.Runtime.InteropServices;

namespace LoggingConsole.Test
{
    partial class Program
    {
      	static void Main(string[] args)
        {
          	[DllImport("kernel32.dll")] static extern bool SetConsoleCP(uint pagenum);
        		[DllImport("kernel32.dll")] static extern bool SetConsoleOutputCP(uint pagenum);
            SetConsoleCP(65001);        //   utf-8 (Unicode)   
            SetConsoleOutputCP(65001);  //   utf-8 (Unicode)   
 
            Console.WriteLine($"Hello, World!");
        }
    }
}

      
      






All Articles