Pelokalan terjamin / Russification dari konsol Windows

pengantar

Aplikasi konsol masih menjadi jenis aplikasi yang paling populer, sebagian besar pengembang mengasah arsitektur dan logika bisnis mereka di konsol. Pada saat yang sama, mereka sering menghadapi masalah pelokalan - teks Rusia, yang cukup tercermin dalam file sumber, ketika ditampilkan di konsol mengambil bentuk yang disebut. "krakozyabr".





Secara umum, melokalkan konsol Windows dengan paket bahasa yang sesuai tidaklah sulit. Namun demikian, solusi yang lengkap dan tidak ambigu untuk masalah ini, pada dasarnya, belum ditemukan. Alasan untuk ini terutama terletak pada sifat konsol, yang, sebagai komponen sistem yang diimplementasikan oleh kelas statis System.Console, mengekspos metodenya ke aplikasi melalui program shell sistem seperti baris perintah atau prosesor perintah (cmd. exe), PowerShell, Terminal, dan lainnya.

Faktanya, konsol berada di bawah kendali ganda - aplikasi dan shell, yang merupakan situasi konflik potensial, terutama dalam hal penggunaan pengkodean.





Materi ini tidak menawarkan algoritme tindakan yang ketat, tetapi ditujukan untuk mendeskripsikan masalah utama yang pasti akan dihadapi oleh pengembang aplikasi konsol yang dilokalkan, serta beberapa cara yang mungkin untuk mengatasinya. Diasumsikan bahwa ini akan memungkinkan pengembang untuk membentuk strategi untuk bekerja dengan konsol yang dilokalkan dan secara efektif menerapkan kemampuan teknis yang ada, yang sebagian besar dijelaskan dengan baik dan dihilangkan di sini.





Jenis konsol

Secara umum, fungsi konsol tersebut adalah sebagai berikut:





  • manajemen sistem operasi dan lingkungan sistem aplikasi berdasarkan penggunaan perangkat input-output sistem standar (layar dan keyboard), menggunakan perintah dari sistem operasi dan / atau konsol itu sendiri;





  • - , -.





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. Hasil dari perintah konsol Echo ffffff ffffff
. 1. Echo ffffff

50% , .2.





Tab.  2. Hasil dari menjalankan aplikasi 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. Setel halaman kode konsol default ke CP65001 (utf-8 Unicode) atau CP1251 (Windows-1251-Cyr), lihat tip 5 ;





  3. Kembangkan aplikasi dalam pengkodean Unicode utf-8;





  4. Kontrol pengkodean file kode sumber, file data teks, misalnya, menggunakan Notepad ++;





  5. Menerapkan pengelolaan terprogram dari pelokalan aplikasi di konsol, contoh di bawah ini di bawah potongan:





Contoh menyetel halaman kode secara terprogram dan melokalkan aplikasi di konsol
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