保証されたローカリゼーション/ Windowsコンソールのロシア化

前書き

コンソールアプリケーションは依然として最も人気のあるタイプのアプリケーションであり、ほとんどの開発者はコンソールでアーキテクチャとビジネスロジックを磨いています。同時に、彼らはしばしばローカリゼーションの問題に直面します-コンソールに表示されたときにソースファイルに非常に適切に反映されているロシア語のテキストは、いわゆる形式を取ります。「krakozyabr」。





一般に、適切な言語パックを使用してWindowsコンソールをローカライズすることは難しくありません。それにもかかわらず、本質的に、この問題に対する完全で明白な解決策はまだ見つかっていません。この理由は主に、静的クラスSystem.Consoleによって実装されるシステムコンポーネントであるコンソールの性質にあり、コマンドラインやコマンドプロセッサ(cmd)などのシステムシェルプログラムを介してそのメソッドをアプリケーションに公開します。 exe)、PowerShell、ターミナルなど。

実際、コンソールはアプリケーションとシェルの2つの制御下にあります。これは、主にエンコーディングの使用に関して、競合する可能性のある状況です。





この資料は、厳密なアクションアルゴリズムを提供していませんが、ローカライズされたコンソールアプリケーションの開発者が必然的に遭遇する主要な問題と、それらを解決するためのいくつかの可能な方法を説明することを目的としています。これにより、開発者はローカライズされたコンソールを操作するための戦略を立て、既存の技術的機能を効果的に実装できるようになると想定されます。これらのほとんどは十分に説明されているため、ここでは省略します。





コンソールの種類

一般に、コンソール機能は次のとおりです。





  • オペレーティングシステムおよび/またはコンソール自体のコマンドを使用した、標準システム入出力デバイス(画面およびキーボード)の使用に基づく、オペレーティングシステムおよびアプリケーションのシステム環境の管理。





  • - , -.





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 .





タブ。 1.コンソールコマンドEchoffffffffffffの結果
. 1. Echo ffffff

50% , .2.





タブ。 2.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. デフォルトのコンソールコードページをCP65001(utf-8 Unicode)またはCP1251(Windows-1251-Cyr)に設定します。ヒント5を参照してください





  3. utf-8Unicodeエンコーディングでアプリケーションを開発します。





  4. メモ帳++を使用して、ソースコードファイル、テキストデータファイルのエンコーディングを制御します。





  5. コンソールでアプリケーションローカリゼーションのプログラムによる管理を実装します。以下の例をカットします。





プログラムでコードページを設定し、コンソールでアプリケーションをローカライズする例
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