Console Класс

Определение

Предоставляет стандартные потоки для консольных приложений: входной, выходной и поток сообщений об ошибках. Этот класс не наследуется.

public ref class Console abstract sealed
public ref class Console sealed
public static class Console
public sealed class Console
type Console = class
Public Class Console
Public NotInheritable Class Console
Наследование
Console

Примеры

В следующем примере показано, как считывать данные из и записывать данные в стандартные входные и выходные потоки. Обратите внимание, что эти потоки можно перенаправить с помощью SetIn методов и SetOut методов.

using namespace System;

int main()
{
   Console::Write( L"Hello " );
   Console::WriteLine( L"World!" );
   Console::Write( L"Enter your name: " );
   String^ name = Console::ReadLine();
   Console::Write( L"Good day, " );
   Console::Write( name );
   Console::WriteLine( L"!" );
}
// The example displays output similar to the following:
//       Hello World!
//       Enter your name: James
//       Good day, James!
using System;

public class Example {
    public static void Main()
    {
        Console.Write("Hello ");
        Console.WriteLine("World!");
        Console.Write("Enter your name: ");
        string name = Console.ReadLine();
        Console.Write("Good day, ");
        Console.Write(name);
        Console.WriteLine("!");
    }
}
// The example displays output similar to the following:
//       Hello World!
//       Enter your name: James
//       Good day, James!
Public Class Example
    Public Shared Sub Main()
        Console.Write("Hello ")
        Console.WriteLine("World!")
        Console.Write("Enter your name: ")
        Dim name As String = Console.ReadLine()
        Console.Write("Good day, ")
        Console.Write(name)
        Console.WriteLine("!")
    End Sub
End Class 
' The example displays output similar to the following:
'        Hello World!
'        Enter your name: James
'        Good day, James!
module Example

open System

[<EntryPoint>]
let main argv =
    Console.Write("Hello ")
    Console.WriteLine("World!")
    Console.Write("Enter your name: ")
    let name = Console.ReadLine()
    Console.Write("Good day, ")
    Console.Write(name)
    Console.WriteLine("!")
    0
    
// The example displays output similar to the following:
//       Hello World!
//       Enter your name: James
//       Good day, James!

Комментарии

Консоль — это окно операционной системы, в котором пользователи взаимодействуют с операционной системой или текстовым консольным приложением, вводя ввод текста с помощью клавиатуры компьютера и считывая текстовые выходные данные из терминала компьютера. Например, в операционной системе Windows консоль называется окном командной строки и принимает команды MS-DOS. Этот Console класс обеспечивает базовую поддержку приложений, которые считывают символы и записывают символы в консоль.

Сведения о разработке с помощью Console класса см. в следующих разделах:

Потоки ввода-вывода консоли

При запуске консольного приложения операционная система автоматически связывает три потока ввода-вывода с консолью: стандартный входной поток, стандартный выходной поток и стандартный поток вывода ошибок. Приложение может считывать входные данные пользователя из стандартного входного потока; запись нормальных данных в стандартный выходной поток; и запись данных об ошибках в стандартный поток вывода ошибок. Эти потоки представлены приложению в виде значений Console.InConsole.Outи Console.Error свойств.

По умолчанию значением In свойства является System.IO.TextReader объект, представляющий клавиатуру, а значения Out свойств и Error свойств представляют System.IO.TextWriter собой объекты, представляющие окно консоли. Однако эти свойства можно задать для потоков, которые не представляют окно консоли или клавиатуры; Например, эти свойства можно задать для потоков, представляющих файлы. Чтобы перенаправить стандартный вход, стандартный выход или стандартный поток ошибок, вызовите Console.SetInConsole.SetOutили Console.SetError метод соответственно. Операции ввода-вывода, использующие эти потоки, синхронизируются, что означает, что несколько потоков могут считывать потоки или записывать их в них. Это означает, что методы, которые обычно асинхронны, например TextReader.ReadLineAsync, выполняются синхронно, если объект представляет поток консоли.

Примечание

Не используйте Console класс для отображения выходных данных в автоматических приложениях, таких как серверные приложения. Вызовы таких методов, как Console.Write и Console.WriteLine не влияют на приложения графического интерфейса пользователя.

Console Члены класса, которые обычно работают, когда базовый поток направляется в консоль, может вызвать исключение, если поток перенаправляется, например, в файл. Запрограммируйте приложение для перехвата System.IO.IOException исключений при перенаправлении стандартного потока. Можно также использовать IsOutputRedirectedсвойства и IsInputRedirectedIsErrorRedirected свойства, чтобы определить, перенаправляется ли стандартный поток перед выполнением операции, которая создает System.IO.IOException исключение.

Иногда бывает полезно явно вызывать члены объектов потока, Outпредставленных свойствами и Error свойствамиIn. Например, по умолчанию Console.ReadLine метод считывает входные данные из стандартного входного потока. Аналогичным образом Console.WriteLine метод записывает данные в стандартный выходной поток, за которым следует строка завершения строки по умолчанию, которую можно найти по адресу Environment.NewLine. Console Однако класс не предоставляет соответствующий метод записи данных в стандартный поток вывода ошибок или свойство для изменения строки завершения строки для данных, записанных в этот поток.

Эту проблему можно решить, задав TextWriter.NewLine для свойства Out или Error свойства другую строку завершения строки. Например, следующая инструкция C# задает строку завершения строки для стандартного потока вывода ошибок в две последовательности возврата каретки и канала строки:

Console.Error.NewLine = "\r\n\r\n";

Затем можно явно вызвать WriteLine метод объекта потока вывода ошибок, как показано в следующей инструкции C#:

Console.Error.WriteLine();

Окно буфера экрана и консоли

Двумя тесно связанными функциями консоли являются буфер экрана и окно консоли. Текст фактически считывается из или записывается в потоки, принадлежащие консоли, но, как представляется, считывается из области, принадлежащей консоли, называемой буфером экрана. Буфер экрана является атрибутом консоли и упорядочен как прямоугольная сетка строк и столбцов, где каждое пересечение сетки или ячейка символов может содержать символ. Каждый символ имеет собственный цвет переднего плана, и каждая ячейка символа имеет собственный цвет фона.

Буфер экрана просматривается через прямоугольную область, называемую окном консоли. Окно консоли является другим атрибутом консоли; это не сама консоль, которая является окном операционной системы. Окно консоли расположено в строках и столбцах, меньше или равно размеру буфера экрана и может быть перемещено для просмотра различных областей базового буфера экрана. Если буфер экрана больше окна консоли, консоль автоматически отображает полосы прокрутки, чтобы окно консоли можно было переместить по области буфера экрана.

Курсор указывает положение буфера экрана, в котором текст в данный момент считывается или записывается. Курсор можно скрыть или сделать видимым, а его высота может быть изменена. Если курсор виден, положение окна консоли перемещается автоматически, поэтому курсор всегда находится в представлении.

Источником координат ячейки символов в буфере экрана является верхний левый угол, а позиции курсора и окна консоли измеряются относительно этого источника. Используйте отсчитываемые от нуля индексы для указания позиций; то есть укажите самую верхнюю строку как строку 0, а самый левый столбец — как столбец 0. Максимальное значение индексов строк и столбцов равно Int16.MaxValue.

Поддержка Юникода для консоли

Как правило, консоль считывает входные данные и записывает выходные данные с помощью текущей кодовой страницы консоли, которая определяется языковым стандартом системы по умолчанию. Кодовая страница может обрабатывать только подмножество доступных символов Юникода, поэтому при попытке отобразить символы, которые не сопоставлены с определенной кодовой страницей, консоль не сможет отображать все символы или представлять их точно. Приведенный ниже пример иллюстрирует данную проблему. Он пытается отобразить символы кирилличного алфавита от U+0410 до U+044F в консоли. Если вы запускаете пример в системе, использующую кодовую страницу консоли 437, каждый символ заменяется вопросительным знаком (?), так как кириллицы не сопоставляются с символами в кодовой странице 437.

using System;

public class Example
{
   public static void Main()
   {
      // Create a Char array for the modern Cyrillic alphabet,
      // from U+0410 to U+044F.
      int nChars = 0x044F - 0x0410 + 1;
      char[] chars = new char[nChars];
      ushort codePoint = 0x0410;
      for (int ctr = 0; ctr < chars.Length; ctr++) {
        chars[ctr] = (char)codePoint;
        codePoint++;
      }

      Console.WriteLine("Current code page: {0}\n",
                        Console.OutputEncoding.CodePage);
      // Display the characters.
      foreach (var ch in chars) {
         Console.Write("{0}  ", ch);
         if (Console.CursorLeft >= 70)
            Console.WriteLine();
      }
   }
}
// The example displays the following output:
//    Current code page: 437
//
//    ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?
//    ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?
//    ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?
Module Example
   Public Sub Main()
      ' Create a Char array for the modern Cyrillic alphabet, 
      ' from U+0410 to U+044F.
      Dim nChars As Integer = &h44F - &h0410
      Dim chars(nChars) As Char
      Dim codePoint As UInt16 = &h0410
      For ctr As Integer = 0 To chars.Length - 1
        chars(ctr) = ChrW(codePoint)
        codePoint += CType(1, UShort)
      Next   
         
      Console.WriteLine("Current code page: {0}", 
                        Console.OutputEncoding.CodePage)
      Console.WriteLine()
      ' Display the characters.
      For Each ch In chars
         Console.Write("{0}  ", ch)
         If Console.CursorLeft >= 70 Then Console.WriteLine()
      Next
   End Sub
End Module
' The example displays the following output:
'       Current code page: 437
'       
'       ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?
'       ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?
'       ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?
open System

// Create a char List for the modern Cyrillic alphabet,
// from U+0410 to U+044F.
let chars =
    [ for codePoint in 0x0410 .. 0x044F do
        Convert.ToChar codePoint ]

printfn "Current code page: %i\n" Console.OutputEncoding.CodePage
// Display the characters.
for ch in chars do
    printf "%c  " ch
    if Console.CursorLeft >= 70 then Console.WriteLine()

// The example displays the following output:
//    Current code page: 437
//
//    ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?
//    ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?
//    ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?

Помимо поддержки кодовых страниц класс Console поддерживает кодировку UTF-8 с классом UTF8Encoding . Начиная с платформа .NET Framework 4.5, Console класс также поддерживает кодировку UTF-16 с классомUnicodeEncoding. Отображение символов Юникода в консоли. you set the OutputEncoding property to either UTF8Encoding or UnicodeEncoding.

Для поддержки символов Юникода кодировщик должен распознать определенный символ Юникода, а также требуется шрифт с глифами, необходимыми для отрисовки этого символа. Чтобы успешно отобразить символы Юникода в консоли, для шрифта консоли необходимо задать шрифт, отличный от растра, или шрифт TrueType, например Consolas или Lucida Console. В следующем примере показано, как программно изменить шрифт с растрового шрифта на Lucida Console.

using System;
using System.Runtime.InteropServices;

public class Example
{
   [DllImport("kernel32.dll", SetLastError = true)]
   static extern IntPtr GetStdHandle(int nStdHandle);

   [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
   static extern bool GetCurrentConsoleFontEx(
          IntPtr consoleOutput,
          bool maximumWindow,
          ref CONSOLE_FONT_INFO_EX lpConsoleCurrentFontEx);

   [DllImport("kernel32.dll", SetLastError = true)]
   static extern bool SetCurrentConsoleFontEx(
          IntPtr consoleOutput,
          bool maximumWindow,
          CONSOLE_FONT_INFO_EX consoleCurrentFontEx);

   private const int STD_OUTPUT_HANDLE = -11;
   private const int TMPF_TRUETYPE = 4;
   private const int LF_FACESIZE = 32;
   private static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);

   public static unsafe void Main()
   {
      string fontName = "Lucida Console";
      IntPtr hnd = GetStdHandle(STD_OUTPUT_HANDLE);
      if (hnd != INVALID_HANDLE_VALUE) {
         CONSOLE_FONT_INFO_EX info = new CONSOLE_FONT_INFO_EX();
         info.cbSize = (uint) Marshal.SizeOf(info);
         bool tt = false;
         // First determine whether there's already a TrueType font.
         if (GetCurrentConsoleFontEx(hnd, false, ref info)) {
            tt = (info.FontFamily & TMPF_TRUETYPE) == TMPF_TRUETYPE;
            if (tt) {
               Console.WriteLine("The console already is using a TrueType font.");
               return;
            }
            // Set console font to Lucida Console.
            CONSOLE_FONT_INFO_EX newInfo = new CONSOLE_FONT_INFO_EX();
            newInfo.cbSize = (uint) Marshal.SizeOf(newInfo);
            newInfo.FontFamily = TMPF_TRUETYPE;
            IntPtr ptr = new IntPtr(newInfo.FaceName);
            Marshal.Copy(fontName.ToCharArray(), 0, ptr, fontName.Length);
            // Get some settings from current font.
            newInfo.dwFontSize = new COORD(info.dwFontSize.X, info.dwFontSize.Y);
            newInfo.FontWeight = info.FontWeight;
            SetCurrentConsoleFontEx(hnd, false, newInfo);
         }
      }
    }

   [StructLayout(LayoutKind.Sequential)]
   internal struct COORD
   {
      internal short X;
      internal short Y;

      internal COORD(short x, short y)
      {
         X = x;
         Y = y;
      }
   }

   [StructLayout(LayoutKind.Sequential)]
   internal unsafe struct CONSOLE_FONT_INFO_EX
   {
      internal uint cbSize;
      internal uint nFont;
      internal COORD dwFontSize;
      internal int FontFamily;
      internal int FontWeight;
      internal fixed char FaceName[LF_FACESIZE];
   }
}
Imports System.Runtime.InteropServices

Public Module Example
   ' <DllImport("kernel32.dll", SetLastError = true)>
   Private Declare Function GetStdHandle Lib "Kernel32" (
                   nStdHandle As Integer) As IntPtr

   ' [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
   Private Declare Function GetCurrentConsoleFontEx Lib "Kernel32" ( 
                   consoleOutput As IntPtr, 
                   maximumWindow As Boolean,
                   ByRef lpConsoleCurrentFontEx As CONSOLE_FONT_INFO_EX) As Boolean
          
   ' [DllImport("kernel32.dll", SetLastError = true)]
   Private Declare Function SetCurrentConsoleFontEx Lib "Kernel32"(
                   consoleOutput As IntPtr, 
                   maximumWindow As Boolean,
                   consoleCurrentFontEx As CONSOLE_FONT_INFO_EX) As Boolean
   
   Private Const STD_OUTPUT_HANDLE As Integer = -11
   Private Const TMPF_TRUETYPE As Integer = 4
   Private Const LF_FACESIZE As Integer= 32
   Private INVALID_HANDLE_VALUE As IntPtr = New IntPtr(-1)
   
   Public Sub Main()
      Dim fontName As String = "Lucida Console"
      Dim hnd As IntPtr = GetStdHandle(STD_OUTPUT_HANDLE)
      If hnd <> INVALID_HANDLE_VALUE Then
         Dim info AS CONSOLE_FONT_INFO_EX = New CONSOLE_FONT_INFO_EX()
         info.cbSize = CUInt(Marshal.SizeOf(info))
         Dim tt As Boolean = False
         ' First determine whether there's already a TrueType font.
         If GetCurrentConsoleFontEx(hnd, False, info) Then
            tt = (info.FontFamily And TMPF_TRUETYPE) = TMPF_TRUETYPE
            If tt Then
               Console.WriteLine("The console already is using a TrueType font.")
               Return
            End If
            ' Set console font to Lucida Console.
            Dim newInfo As CONSOLE_FONT_INFO_EX = New CONSOLE_FONT_INFO_EX()
            newInfo.cbSize = CUInt(Marshal.SizeOf(newInfo))          
            newInfo.FontFamily = TMPF_TRUETYPE
            newInfo.FaceName = fontName
            ' Get some settings from current font.
            newInfo.dwFontSize = New COORD(info.dwFontSize.X, info.dwFontSize.Y)
            newInfo.FontWeight = info.FontWeight
            SetCurrentConsoleFontEx(hnd, False, newInfo)
         End If
      End If    
   End Sub
 
   <StructLayout(LayoutKind.Sequential)> Friend Structure COORD
      Friend X As Short
      Friend Y As Short
      
      Friend Sub New(x As Short, y As Short)
         Me.X = x
         Me.Y = y
      End Sub
   End Structure
 
   <StructLayout(LayoutKind.Sequential, CharSet := CharSet.Unicode)> Friend Structure CONSOLE_FONT_INFO_EX 
      Friend cbSize As UInteger
      Friend nFont As UInteger
      Friend dwFontSize As COORD
      Friend FontFamily As Integer
      Friend FontWeight As Integer
      <MarshalAs(UnmanagedType.ByValTStr, SizeConst := 32)> Friend FaceName As String
   End Structure 
End Module
module Example

open System
open System.Runtime.InteropServices

[<Literal>]
let STD_OUTPUT_HANDLE = -11

[<Literal>]
let TMPF_TRUETYPE = 4

[<Literal>]
let LF_FACESIZE = 32

let INVALID_HANDLE_VALUE = IntPtr(-1)


[<Struct>]
[<StructLayout(LayoutKind.Sequential)>]
type COORD =
    val mutable X: int16
    val mutable Y: int16

    internal new(x: int16, y: int16) =
        { X = x
          Y = y }

[<Struct>]
[<StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)>]
type CONSOLE_FONT_INFO_EX =
    val mutable cbSize: uint32
    val mutable nFont: uint32
    val mutable dwFontSize: COORD
    val mutable FontFamily: int
    val mutable FontWeight: int
    [<MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)>]
    val mutable FaceName: string

[<DllImport("kernel32.dll", SetLastError = true)>]
extern IntPtr GetStdHandle(int nStdHandle)

[<DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)>]
extern bool GetCurrentConsoleFontEx(IntPtr consoleOutput, bool maximumWindow, CONSOLE_FONT_INFO_EX lpConsoleCurrentFontEx)

[<DllImport("kernel32.dll", SetLastError = true)>]
extern bool SetCurrentConsoleFontEx(IntPtr consoleOutput, bool maximumWindow, CONSOLE_FONT_INFO_EX consoleCurrentFontEx)

[<EntryPoint>]
let main argv =
    let fontName = "Lucida Console"
    let hnd = GetStdHandle(STD_OUTPUT_HANDLE)
    if hnd <> INVALID_HANDLE_VALUE then
        let mutable info = CONSOLE_FONT_INFO_EX()
        info.cbSize <- uint32 (Marshal.SizeOf(info))
        // First determine whether there's already a TrueType font.
        if (GetCurrentConsoleFontEx(hnd, false, info)) then
            if (((info.FontFamily) &&& TMPF_TRUETYPE) = TMPF_TRUETYPE) then
                Console.WriteLine("The console already is using a TrueType font.")
            else
                // Set console font to Lucida Console.
                let mutable newInfo = CONSOLE_FONT_INFO_EX()
                newInfo.cbSize <- uint32 (Marshal.SizeOf(newInfo))
                newInfo.FontFamily <- TMPF_TRUETYPE
                newInfo.FaceName <- fontName
                // Get some settings from current font.
                newInfo.dwFontSize <- COORD(info.dwFontSize.X, info.dwFontSize.Y)
                newInfo.FontWeight <- info.FontWeight
                SetCurrentConsoleFontEx(hnd, false, newInfo) |> ignore
                Console.WriteLine("The console is now using a TrueType font.")

    // Return zero for success
    0

Однако шрифты TrueType могут отображать только подмножество глифов. Например, шрифт консоли Lucida отображает только 643 из примерно 64 000 доступных символов от U+0021 до U+FB02. Чтобы узнать, какие символы поддерживает определенный шрифт, откройте апплеску "Шрифты" в панель управления, выберите параметр "Найти символ" и выберите шрифт, набор символов которого вы хотите изучить в списке шрифтов окна "Карта символов".

Windows использует связывание шрифтов для отображения глифов, недоступных в определенном шрифте. Сведения о связывании шрифтов для отображения дополнительных наборов символов см. в разделе "Пошаговые инструкции по глобализации: шрифты". Связанные шрифты определяются в подразделе реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink. Каждая запись, связанная с этим подразделом, соответствует имени базового шрифта, а его значение — массив строк, определяющий файлы шрифтов и шрифты, связанные с базовым шрифтом. Каждый элемент массива определяет связанный шрифт и принимает имя шрифта-файла формы, имя шрифта. В следующем примере показано, как программно определить связанный шрифт с именем SimSun, найденный в файле шрифта simsun.ttc, в котором отображаются символы Упрощенного хэна.

using Microsoft.Win32;
using System;

public class Example
{
   public static void Main()
   {
      string valueName = "Lucida Console";
      string newFont = "simsun.ttc,SimSun";
      string[] fonts = null;
      RegistryValueKind kind = 0;
      bool toAdd;

      RegistryKey key = Registry.LocalMachine.OpenSubKey(
                 @"Software\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink",
                 true);
      if (key == null) {
         Console.WriteLine("Font linking is not enabled.");
      }
      else {
         // Determine if the font is a base font.
         string[] names = key.GetValueNames();
         if (Array.Exists(names, s => s.Equals(valueName,
                                      StringComparison.OrdinalIgnoreCase))) {
            // Get the value's type.
            kind = key.GetValueKind(valueName);

            // Type should be RegistryValueKind.MultiString, but we can't be sure.
            switch (kind) {
               case RegistryValueKind.String:
                  fonts = new string[] { (string) key.GetValue(valueName) };
                  break;
               case RegistryValueKind.MultiString:
                  fonts = (string[]) key.GetValue(valueName);
                  break;
               case RegistryValueKind.None:
                  // Do nothing.
                  fonts = new string[] { };
                  break;
            }
            // Determine whether SimSun is a linked font.
            if (Array.FindIndex(fonts, s =>s.IndexOf("SimSun",
                                       StringComparison.OrdinalIgnoreCase) >=0) >= 0) {
               Console.WriteLine("Font is already linked.");
               toAdd = false;
            }
            else {
               // Font is not a linked font.
               toAdd = true;
            }
         }
         else {
            // Font is not a base font.
            toAdd = true;
            fonts = new string[] { };
         }

         if (toAdd) {
            Array.Resize(ref fonts, fonts.Length + 1);
            fonts[fonts.GetUpperBound(0)] = newFont;
            // Change REG_SZ to REG_MULTI_SZ.
            if (kind == RegistryValueKind.String)
               key.DeleteValue(valueName, false);

            key.SetValue(valueName, fonts, RegistryValueKind.MultiString);
            Console.WriteLine("SimSun added to the list of linked fonts.");
         }
      }

      if (key != null) key.Close();
   }
}
Imports Microsoft.Win32

Module Example
   Public Sub Main()
      Dim valueName As String = "Lucida Console"
      Dim newFont As String = "simsun.ttc,SimSun"
      Dim fonts() As String = Nothing
      Dim kind As RegistryValueKind 
      Dim toAdd As Boolean
      
      Dim key As RegistryKey = Registry.LocalMachine.OpenSubKey( 
                 "Software\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink", 
                 True)
      If key Is Nothing Then
         Console.WriteLine("Font linking is not enabled.")
      Else
         ' Determine if the font is a base font.
         Dim names() As String = key.GetValueNames()
         If Array.Exists(names, Function(s) s.Equals(valueName, 
                                                     StringComparison.OrdinalIgnoreCase))
            ' Get the value's type.
            kind = key.GetValueKind(valueName)

            ' Type should be RegistryValueKind.MultiString, but we can't be sure.
            Select Case kind
               Case RegistryValueKind.String
                  fonts = { CStr(key.GetValue(valueName)) }   
               Case RegistryValueKind.MultiString
                  fonts = CType(key.GetValue(valueName), String())
               Case RegistryValueKind.None
                  ' Do nothing.
                  fonts = { }
            End Select 
            ' Determine whether SimSun is a linked font.
            If Array.FindIndex(fonts, Function(s) s.IndexOf("SimSun", 
                                      StringComparison.OrdinalIgnoreCase) >=0) >= 0 Then
               Console.WriteLine("Font is already linked.")
               toAdd = False
            Else
               ' Font is not a linked font.
               toAdd = True
            End If
         Else
            ' Font is not a base font.
            toAdd = True
            fonts = { }
         End If

         If toAdd Then  
            Array.Resize(fonts, fonts.Length + 1)
            fonts(fonts.GetUpperBound(0)) = newFont
            ' Change REG_SZ to REG_MULTI_SZ.
            If kind = RegistryValueKind.String Then
               key.DeleteValue(valueName, False)
            End If
            key.SetValue(valueName, fonts, RegistryValueKind.MultiString)
            Console.WriteLine("SimSun added to the list of linked fonts.")
         End If                     
      End If
      
      If key IsNot Nothing Then key.Close()
   End Sub
End Module
open System
open Microsoft.Win32

let valueName = "Lucida Console"
let newFont = "simsun.ttc,SimSun"

let key =
    Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink", true)
if isNull key then
    printfn "Font linking is not enabled."
else
    // Determine if the font is a base font.
    let names = key.GetValueNames()

    let (fonts, kind, toAdd) =
        if names |> Array.exists (fun s -> s.Equals(valueName, StringComparison.OrdinalIgnoreCase)) then
            // Get the value's type.
            let kind = key.GetValueKind(valueName)

            // Type should be RegistryValueKind.MultiString, but we can't be sure.
            let fonts =
                match kind with
                | RegistryValueKind.String -> [| key.GetValue(valueName) :?> string |]
                | RegistryValueKind.MultiString -> (key.GetValue(valueName) :?> string array)
                | _ -> [||]

            // Determine whether SimSun is a linked font.
            let toAdd =
                not (fonts |> Array.exists (fun s -> s.IndexOf("SimSun", StringComparison.OrdinalIgnoreCase) >= 0))

            (fonts, kind, toAdd)
        else
            // Font is not a base font.
            ([||], RegistryValueKind.Unknown, true)

    if toAdd then
        // Font is not a linked font.
        let newFonts = Array.append fonts [| newFont |]

        // Change REG_SZ to REG_MULTI_SZ.
        if kind = RegistryValueKind.String then key.DeleteValue(valueName, false)

        key.SetValue(valueName, newFonts, RegistryValueKind.MultiString)
        printfn "SimSun added to the list of linked fonts."
    else
        printfn "Font is already linked."


if not (isNull key) then key.Close()

Поддержка Юникода для консоли имеет следующие ограничения:

  • Кодировка UTF-32 не поддерживается. Единственными поддерживаемыми кодировками Юникода являются UTF-8 и UTF-16, представленные соответствующими классамиUTF8Encoding.UnicodeEncoding

  • Двунаправленные выходные данные не поддерживаются.

  • Отображение символов за пределами базовой многоязычной плоскости (т. е. суррогатных пар) не поддерживается, даже если они определены в связанном файле шрифта.

  • Отображение символов в сложных скриптах не поддерживается.

  • Объединение последовательностей символов (т. е. символов, состоящих из базового символа и одного или нескольких объединенных символов) отображаются в виде отдельных символов. Чтобы обойти это ограничение, можно нормализовать отображаемую строку, вызвав String.Normalize метод перед отправкой выходных данных в консоль. В следующем примере строка, содержащая объединяющую последовательность символов U+0061 U+0308, отображается в консоли как два символа перед нормализацией выходной строки и как один символ после String.Normalize вызова метода.

    using System;
    using System.IO;
    
    public class Example
    {
       public static void Main()
       {
          char[] chars = { '\u0061', '\u0308' };
    
          string combining = new String(chars);
          Console.WriteLine(combining);
    
          combining = combining.Normalize();
          Console.WriteLine(combining);
       }
    }
    // The example displays the following output:
    //       a"
    //       ä
    
    Module Example
       Public Sub Main()
          Dim chars() As Char = { ChrW(&h0061), ChrW(&h0308) }
       
          Dim combining As String = New String(chars)
          Console.WriteLine(combining)
          
          combining = combining.Normalize()
          Console.WriteLine(combining)
       End Sub
    End Module
    ' The example displays the following output:
    '       a"
    '       ä
    
    open System
    
    let chars = [| '\u0061'; '\u0308' |]
    
    let combining = String chars
    Console.WriteLine combining
    
    let combining2 = combining.Normalize()
    Console.WriteLine combining2
    
    
    // The example displays the following output:
    //       a"
    //       ä
    

    Обратите внимание, что нормализация является жизнеспособным решением, только если стандарт Юникода для символа включает предварительно составленную форму, соответствующую определенной последовательности символов.

  • Если шрифт предоставляет глиф для кодовой точки в области частного использования, будет отображаться глиф. Тем не менее, поскольку символы в области частного использования зависят от приложения, это может быть не ожидаемый глиф.

В следующем примере отображается диапазон символов Юникода в консоли. В примере принимаются три параметра командной строки: начало диапазона, конец отображаемого диапазона и использование текущей кодировки консоли (false) или кодировки UTF-16 (true). Предполагается, что консоль использует шрифт TrueType.

using System;
using System.IO;
using System.Globalization;
using System.Text;

public static class DisplayChars
{
   private static void Main(string[] args)
   {
      uint rangeStart = 0;
      uint rangeEnd = 0;
      bool setOutputEncodingToUnicode = true;
      // Get the current encoding so we can restore it.
      Encoding originalOutputEncoding = Console.OutputEncoding;

    try
    {
         switch(args.Length)
         {
            case 2:
               rangeStart = uint.Parse(args[0], NumberStyles.HexNumber);
               rangeEnd = uint.Parse(args[1], NumberStyles.HexNumber);
               setOutputEncodingToUnicode = true;
               break;
            case 3:
               if (! uint.TryParse(args[0], NumberStyles.HexNumber, null, out rangeStart))
                  throw new ArgumentException(String.Format("{0} is not a valid hexadecimal number.", args[0]));

               if (!uint.TryParse(args[1], NumberStyles.HexNumber, null, out rangeEnd))
                  throw new ArgumentException(String.Format("{0} is not a valid hexadecimal number.", args[1]));

               bool.TryParse(args[2], out setOutputEncodingToUnicode);
               break;
            default:
               Console.WriteLine("Usage: {0} <{1}> <{2}> [{3}]",
                                 Environment.GetCommandLineArgs()[0],
                                 "startingCodePointInHex",
                                 "endingCodePointInHex",
                                 "<setOutputEncodingToUnicode?{true|false, default:false}>");
               return;
         }

         if (setOutputEncodingToUnicode) {
            // This won't work before .NET Framework 4.5.
            try {
               // Set encoding using endianness of this system.
               // We're interested in displaying individual Char objects, so
               // we don't want a Unicode BOM or exceptions to be thrown on
               // invalid Char values.
               Console.OutputEncoding = new UnicodeEncoding(! BitConverter.IsLittleEndian, false);
               Console.WriteLine("\nOutput encoding set to UTF-16");
            }
            catch (IOException) {
               Console.OutputEncoding = new UTF8Encoding();
               Console.WriteLine("Output encoding set to UTF-8");
            }
         }
         else {
            Console.WriteLine("The console encoding is {0} (code page {1})",
                              Console.OutputEncoding.EncodingName,
                              Console.OutputEncoding.CodePage);
         }
         DisplayRange(rangeStart, rangeEnd);
      }
      catch (ArgumentException ex) {
         Console.WriteLine(ex.Message);
      }
      finally {
         // Restore console environment.
         Console.OutputEncoding = originalOutputEncoding;
      }
   }

   public static void DisplayRange(uint start, uint end)
   {
      const uint upperRange = 0x10FFFF;
      const uint surrogateStart = 0xD800;
      const uint surrogateEnd = 0xDFFF;

      if (end <= start) {
         uint t = start;
         start = end;
         end = t;
      }

      // Check whether the start or end range is outside of last plane.
      if (start > upperRange)
         throw new ArgumentException(String.Format("0x{0:X5} is outside the upper range of Unicode code points (0x{1:X5})",
                                                   start, upperRange));
      if (end > upperRange)
         throw new ArgumentException(String.Format("0x{0:X5} is outside the upper range of Unicode code points (0x{0:X5})",
                                                   end, upperRange));

      // Since we're using 21-bit code points, we can't use U+D800 to U+DFFF.
      if ((start < surrogateStart & end > surrogateStart) || (start >= surrogateStart & start <= surrogateEnd ))
         throw new ArgumentException(String.Format("0x{0:X5}-0x{1:X5} includes the surrogate pair range 0x{2:X5}-0x{3:X5}",
                                                   start, end, surrogateStart, surrogateEnd));
      uint last = RoundUpToMultipleOf(0x10, end);
      uint first = RoundDownToMultipleOf(0x10, start);

      uint rows = (last - first) / 0x10;

      for (uint r = 0; r < rows; ++r) {
         // Display the row header.
         Console.Write("{0:x5} ", first + 0x10 * r);

         for (uint c = 0; c < 0x10; ++c) {
            uint cur = (first + 0x10 * r + c);
            if (cur  < start) {
               Console.Write($" {(char)(0x20)} ");
            }
            else if (end < cur) {
               Console.Write($" {(char)(0x20)} ");
            }
            else {
               // the cast to int is safe, since we know that val <= upperRange.
               String chars = Char.ConvertFromUtf32( (int) cur);
               // Display a space for code points that are not valid characters.
               if (CharUnicodeInfo.GetUnicodeCategory(chars[0]) ==
                                               UnicodeCategory.OtherNotAssigned)
                  Console.Write($" {(char)(0x20)} ");
               // Display a space for code points in the private use area.
               else if (CharUnicodeInfo.GetUnicodeCategory(chars[0]) ==
                                              UnicodeCategory.PrivateUse)
                 Console.Write($" {(char)(0x20)} ");
               // Is surrogate pair a valid character?
               // Note that the console will interpret the high and low surrogate
               // as separate (and unrecognizable) characters.
               else if (chars.Length > 1 && CharUnicodeInfo.GetUnicodeCategory(chars, 0) ==
                                            UnicodeCategory.OtherNotAssigned)
                  Console.Write($" {(char)(0x20)} ");
               else
                  Console.Write($" {chars} ");
            }

            switch (c) {
               case 3: case 11:
                  Console.Write("-");
                  break;
               case 7:
                  Console.Write("--");
                  break;
            }
         }

         Console.WriteLine();
         if (0 < r && r % 0x10 == 0)
            Console.WriteLine();
      }
   }

   private static uint RoundUpToMultipleOf(uint b, uint u)
   {
      return RoundDownToMultipleOf(b, u) + b;
   }

   private static uint RoundDownToMultipleOf(uint b, uint u)
   {
      return u - (u % b);
   }
}
// If the example is run with the command line
//       DisplayChars 0400 04FF true
// the example displays the Cyrillic character set as follows:
//       Output encoding set to UTF-16
//       00400  Ѐ  Ё  Ђ  Ѓ - Є  Ѕ  І  Ї -- Ј  Љ  Њ  Ћ - Ќ  Ѝ  Ў  Џ
//       00410  А  Б  В  Г - Д  Е  Ж  З -- И  Й  К  Л - М  Н  О  П
//       00420  Р  С  Т  У - Ф  Х  Ц  Ч -- Ш  Щ  Ъ  Ы - Ь  Э  Ю  Я
//       00430  а  б  в  г - д  е  ж  з -- и  й  к  л - м  н  о  п
//       00440  р  с  т  у - ф  х  ц  ч -- ш  щ  ъ  ы - ь  э  ю  я
//       00450  ѐ  ё  ђ  ѓ - є  ѕ  і  ї -- ј  љ  њ  ћ - ќ  ѝ  ў  џ
//       00460  Ѡ  ѡ  Ѣ  ѣ - Ѥ  ѥ  Ѧ  ѧ -- Ѩ  ѩ  Ѫ  ѫ - Ѭ  ѭ  Ѯ  ѯ
//       00470  Ѱ  ѱ  Ѳ  ѳ - Ѵ  ѵ  Ѷ  ѷ -- Ѹ  ѹ  Ѻ  ѻ - Ѽ  ѽ  Ѿ  ѿ
//       00480  Ҁ  ҁ  ҂  ҃ - ҄  ҅  ҆  ҇ -- ҈  ҉  Ҋ  ҋ - Ҍ  ҍ  Ҏ  ҏ
//       00490  Ґ  ґ  Ғ  ғ - Ҕ  ҕ  Җ  җ -- Ҙ  ҙ  Қ  қ - Ҝ  ҝ  Ҟ  ҟ
//       004a0  Ҡ  ҡ  Ң  ң - Ҥ  ҥ  Ҧ  ҧ -- Ҩ  ҩ  Ҫ  ҫ - Ҭ  ҭ  Ү  ү
//       004b0  Ұ  ұ  Ҳ  ҳ - Ҵ  ҵ  Ҷ  ҷ -- Ҹ  ҹ  Һ  һ - Ҽ  ҽ  Ҿ  ҿ
//       004c0  Ӏ  Ӂ  ӂ  Ӄ - ӄ  Ӆ  ӆ  Ӈ -- ӈ  Ӊ  ӊ  Ӌ - ӌ  Ӎ  ӎ  ӏ
//       004d0  Ӑ  ӑ  Ӓ  ӓ - Ӕ  ӕ  Ӗ  ӗ -- Ә  ә  Ӛ  ӛ - Ӝ  ӝ  Ӟ  ӟ
//       004e0  Ӡ  ӡ  Ӣ  ӣ - Ӥ  ӥ  Ӧ  ӧ -- Ө  ө  Ӫ  ӫ - Ӭ  ӭ  Ӯ  ӯ
//       004f0  Ӱ  ӱ  Ӳ  ӳ - Ӵ  ӵ  Ӷ  ӷ -- Ӹ  ӹ  Ӻ  ӻ - Ӽ  ӽ  Ӿ  ӿ
Imports System.IO
Imports System.Globalization
Imports System.Text

Public Module DisplayChars
   Public Sub Main(args() As String)
      Dim rangeStart As UInteger = 0
      Dim rangeEnd As UInteger = 0
      Dim setOutputEncodingToUnicode As Boolean = True
      ' Get the current encoding so we can restore it.
      Dim originalOutputEncoding As Encoding = Console.OutputEncoding

    Try
         Select Case args.Length
            Case 2
               rangeStart = UInt32.Parse(args(0), NumberStyles.HexNumber)
               rangeEnd = UInt32.Parse(args(1), NumberStyles.HexNumber)
               setOutputEncodingToUnicode = True
            Case 3
               If Not UInt32.TryParse(args(0), NumberStyles.HexNumber, Nothing, rangeStart) Then
                  Throw New ArgumentException(String.Format("{0} is not a valid hexadecimal number.", args(0)))
               End If
               
               If Not UInt32.TryParse(args(1), NumberStyles.HexNumber, Nothing, rangeEnd) Then
                  Throw New ArgumentException(String.Format("{0} is not a valid hexadecimal number.", args(1)))
               End If
               
               Boolean.TryParse(args(2), setOutputEncodingToUnicode)
            Case Else
               Console.WriteLine("Usage: {0} <{1}> <{2}> [{3}]", 
                                 Environment.GetCommandLineArgs()(0), 
                                 "startingCodePointInHex", 
                                 "endingCodePointInHex", 
                                 "<setOutputEncodingToUnicode?{true|false, default:false}>")
               Exit Sub
         End Select
   
         If setOutputEncodingToUnicode Then
            ' This won't work before .NET Framework 4.5.
            Try 
               ' Set encoding Imports endianness of this system.
               ' We're interested in displaying individual Char objects, so 
               ' we don't want a Unicode BOM or exceptions to be thrown on
               ' invalid Char values.
               Console.OutputEncoding = New UnicodeEncoding(Not BitConverter.IsLittleEndian, False) 
               Console.WriteLine("{0}Output encoding set to UTF-16", vbCrLf)
            Catch e As IOException
               Console.OutputEncoding = New UTF8Encoding()
               Console.WriteLine("Output encoding set to UTF-8")
            End Try
         Else
            Console.WriteLine("The console encoding is {0} (code page {1})", 
                              Console.OutputEncoding.EncodingName,
                              Console.OutputEncoding.CodePage)
         End If
         DisplayRange(rangeStart, rangeEnd)
      Catch ex As ArgumentException
         Console.WriteLine(ex.Message)
      Finally
         ' Restore console environment.
         Console.OutputEncoding = originalOutputEncoding
      End Try
   End Sub

   Public Sub DisplayRange(rangeStart As UInteger, rangeEnd As UInteger)
      Const upperRange As UInteger = &h10FFFF
      Const surrogateStart As UInteger = &hD800
      Const surrogateEnd As UInteger = &hDFFF
       
      If rangeEnd <= rangeStart Then
         Dim t As UInteger = rangeStart
         rangeStart = rangeEnd
         rangeEnd = t
      End If

      ' Check whether the start or end range is outside of last plane.
      If rangeStart > upperRange Then
         Throw New ArgumentException(String.Format("0x{0:X5} is outside the upper range of Unicode code points (0x{1:X5})",
                                                   rangeStart, upperRange))                                   
      End If
      If rangeEnd > upperRange Then
         Throw New ArgumentException(String.Format("0x{0:X5} is outside the upper range of Unicode code points (0x{0:X5})",
                                                   rangeEnd, upperRange))
      End If
      ' Since we're using 21-bit code points, we can't use U+D800 to U+DFFF.
      If (rangeStart < surrogateStart And rangeEnd > surrogateStart) OrElse (rangeStart >= surrogateStart And rangeStart <= surrogateEnd )
         Throw New ArgumentException(String.Format("0x{0:X5}-0x{1:X5} includes the surrogate pair range 0x{2:X5}-0x{3:X5}", 
                                                   rangeStart, rangeEnd, surrogateStart, surrogateEnd))         
      End If
      
      Dim last As UInteger = RoundUpToMultipleOf(&h10, rangeEnd)
      Dim first As UInteger = RoundDownToMultipleOf(&h10, rangeStart)

      Dim rows As UInteger = (last - first) \ &h10

      For r As UInteger = 0 To rows - 1
         ' Display the row header.
         Console.Write("{0:x5} ", first + &h10 * r)

         For c As UInteger = 1 To &h10
            Dim cur As UInteger = first + &h10 * r + c
            If cur  < rangeStart Then
               Console.Write(" {0} ", Convert.ToChar(&h20))
            Else If rangeEnd < cur Then
               Console.Write(" {0} ", Convert.ToChar(&h20))
            Else 
               ' the cast to int is safe, since we know that val <= upperRange.
               Dim chars As String = Char.ConvertFromUtf32(CInt(cur))
               ' Display a space for code points that are not valid characters.
               If CharUnicodeInfo.GetUnicodeCategory(chars(0)) = 
                                   UnicodeCategory.OtherNotAssigned Then
                  Console.Write(" {0} ", Convert.ToChar(&h20))
               ' Display a space for code points in the private use area.
               Else If CharUnicodeInfo.GetUnicodeCategory(chars(0)) =
                                        UnicodeCategory.PrivateUse Then
                 Console.Write(" {0} ", Convert.ToChar(&h20))
               ' Is surrogate pair a valid character?
               ' Note that the console will interpret the high and low surrogate
               ' as separate (and unrecognizable) characters.
               Else If chars.Length > 1 AndAlso CharUnicodeInfo.GetUnicodeCategory(chars, 0) = 
                                            UnicodeCategory.OtherNotAssigned Then
                  Console.Write(" {0} ", Convert.ToChar(&h20))
               Else
                  Console.Write(" {0} ", chars) 
               End If   
            End If
            
            Select Case c
               Case 3, 11
                  Console.Write("-")
               Case 7
                  Console.Write("--")
            End Select
         Next

         Console.WriteLine()
         If 0 < r AndAlso r Mod &h10 = 0
            Console.WriteLine()
         End If
      Next
   End Sub

   Private Function RoundUpToMultipleOf(b As UInteger, u As UInteger) As UInteger
      Return RoundDownToMultipleOf(b, u) + b
   End Function

   Private Function RoundDownToMultipleOf(b As UInteger, u As UInteger) As UInteger
      Return u - (u Mod b)
   End Function
End Module
' If the example is run with the command line
'       DisplayChars 0400 04FF true
' the example displays the Cyrillic character set as follows:
'       Output encoding set to UTF-16
'       00400  Ѐ  Ё  Ђ  Ѓ - Є  Ѕ  І  Ї -- Ј  Љ  Њ  Ћ - Ќ  Ѝ  Ў  Џ
'       00410  А  Б  В  Г - Д  Е  Ж  З -- И  Й  К  Л - М  Н  О  П
'       00420  Р  С  Т  У - Ф  Х  Ц  Ч -- Ш  Щ  Ъ  Ы - Ь  Э  Ю  Я
'       00430  а  б  в  г - д  е  ж  з -- и  й  к  л - м  н  о  п
'       00440  р  с  т  у - ф  х  ц  ч -- ш  щ  ъ  ы - ь  э  ю  я
'       00450  ѐ  ё  ђ  ѓ - є  ѕ  і  ї -- ј  љ  њ  ћ - ќ  ѝ  ў  џ
'       00460  Ѡ  ѡ  Ѣ  ѣ - Ѥ  ѥ  Ѧ  ѧ -- Ѩ  ѩ  Ѫ  ѫ - Ѭ  ѭ  Ѯ  ѯ
'       00470  Ѱ  ѱ  Ѳ  ѳ - Ѵ  ѵ  Ѷ  ѷ -- Ѹ  ѹ  Ѻ  ѻ - Ѽ  ѽ  Ѿ  ѿ
'       00480  Ҁ  ҁ  ҂  ҃ - ҄  ҅  ҆  ҇ -- ҈  ҉  Ҋ  ҋ - Ҍ  ҍ  Ҏ  ҏ
'       00490  Ґ  ґ  Ғ  ғ - Ҕ  ҕ  Җ  җ -- Ҙ  ҙ  Қ  қ - Ҝ  ҝ  Ҟ  ҟ
'       004a0  Ҡ  ҡ  Ң  ң - Ҥ  ҥ  Ҧ  ҧ -- Ҩ  ҩ  Ҫ  ҫ - Ҭ  ҭ  Ү  ү
'       004b0  Ұ  ұ  Ҳ  ҳ - Ҵ  ҵ  Ҷ  ҷ -- Ҹ  ҹ  Һ  һ - Ҽ  ҽ  Ҿ  ҿ
'       004c0  Ӏ  Ӂ  ӂ  Ӄ - ӄ  Ӆ  ӆ  Ӈ -- ӈ  Ӊ  ӊ  Ӌ - ӌ  Ӎ  ӎ  ӏ
'       004d0  Ӑ  ӑ  Ӓ  ӓ - Ӕ  ӕ  Ӗ  ӗ -- Ә  ә  Ӛ  ӛ - Ӝ  ӝ  Ӟ  ӟ
'       004e0  Ӡ  ӡ  Ӣ  ӣ - Ӥ  ӥ  Ӧ  ӧ -- Ө  ө  Ӫ  ӫ - Ӭ  ӭ  Ӯ  ӯ
'       004f0  Ӱ  ӱ  Ӳ  ӳ - Ӵ  ӵ  Ӷ  ӷ -- Ӹ  ӹ  Ӻ  ӻ - Ӽ  ӽ  Ӿ  ӿ
module DisplayChars

open System
open System.IO
open System.Globalization
open System.Text

type uint = uint32

let inline roundDownToMultipleOf b u = u - (u % b)

let inline roundUpToMultipleOf b u = roundDownToMultipleOf b u |> (+) b

let displayRange (start: uint) (``end``: uint) =

    let upperRange = 0x10FFFFu
    let surrogateStart = 0xD800u
    let surrogateEnd = 0xDFFFu

    let start, ``end`` =
        if ``end`` <= start then ``end``, start
        else start, ``end``

    // Check whether the start or end range is outside of last plane.
    if start > upperRange then
        invalidArg "start"
            (String.Format("0x{0:X5} is outside the upper range of Unicode code points (0x{1:X5})", start, upperRange))
    if ``end`` > upperRange then
        invalidArg "end"
            (String.Format("0x{0:X5} is outside the upper range of Unicode code points (0x{0:X5})", ``end``, upperRange))

    // Since we're using 21-bit code points, we can't use U+D800 to U+DFFF.
    if (start < surrogateStart && ``end`` > surrogateStart) || (start >= surrogateStart && start <= surrogateEnd) then
        raise
            (ArgumentException
                (String.Format
                    ("0x{0:X5}-0x{1:X5} includes the surrogate pair range 0x{2:X5}-0x{3:X5}", start, ``end``,
                     surrogateStart, surrogateEnd)))
    let last = roundUpToMultipleOf 0x10u ``end``
    let first = roundDownToMultipleOf 0x10u start

    let rows = (last - first) / 0x10u

    for r in 0u .. (rows - 1u) do
        // Display the row header.
        printf "%05x " (first + 0x10u * r)

        for c in 0u .. (0x10u - 1u) do
            let cur = (first + 0x10u * r + c)
            if cur < start || ``end`` < cur then
                printf " %c " (Convert.ToChar 0x20)
            else
                // the cast to int is safe, since we know that val <= upperRange.
                let chars = Char.ConvertFromUtf32(int cur)
                // Display a space for code points that are not valid characters.
                if CharUnicodeInfo.GetUnicodeCategory(chars[0]) = UnicodeCategory.OtherNotAssigned then
                    printf " %c " (Convert.ToChar 0x20)
                else
                    // Display a space for code points in the private use area.
                    if CharUnicodeInfo.GetUnicodeCategory(chars[0]) = UnicodeCategory.PrivateUse then
                        printf " %c " (Convert.ToChar 0x20)
                    else if chars.Length > 1
                            && CharUnicodeInfo.GetUnicodeCategory(chars, 0) = UnicodeCategory.OtherNotAssigned then
                        printf " %c " (Convert.ToChar 0x20)
                    else printf " %s " chars

            match c with
            | 3u
            | 11u -> printf "-"
            | 7u -> printf "--"
            | _ -> ()

        Console.WriteLine()
        if (0u < r && r % 0x10u = 0u) then Console.WriteLine()



[<EntryPoint>]
let main args =
    // Get the current encoding so we can restore it.
    let originalOutputEncoding = Console.OutputEncoding

    try
        try
            let parsedArgs =
                match args.Length with
                | 2 ->
                    Some
                        {| setOutputEncodingToUnicode = true
                           rangeStart = uint.Parse(args[0], NumberStyles.HexNumber)
                           rangeEnd = uint.Parse(args[1], NumberStyles.HexNumber) |}
                | 3 ->
                    let parseHexNumberOrThrow (value: string) parameterName =
                        (uint.TryParse(value, NumberStyles.HexNumber, null))
                        |> function
                        | (false, _) ->
                            invalidArg parameterName (String.Format("{0} is not a valid hexadecimal number.", value))
                        | (true, value) -> value

                    let setOutputEncodingToUnicode =
                        match bool.TryParse args[2] with
                        | true, value -> value
                        | false, _ -> true

                    Some
                        {| setOutputEncodingToUnicode = setOutputEncodingToUnicode
                           rangeStart = parseHexNumberOrThrow args[0] "rangeStart"
                           rangeEnd = parseHexNumberOrThrow args[1] "rangeEnd" |}
                | _ ->
                    printfn "Usage: %s <%s> <%s> [%s]" (Environment.GetCommandLineArgs()[0]) "startingCodePointInHex"
                        "endingCodePointInHex" "<setOutputEncodingToUnicode?{true|false, default:false}>"
                    None

            match parsedArgs with
            | None -> ()
            | Some parsedArgs ->
                if parsedArgs.setOutputEncodingToUnicode then
                    // This won't work before .NET Framework 4.5.
                    try
                        // Set encoding using endianness of this system.
                        // We're interested in displaying individual Char objects, so
                        // we don't want a Unicode BOM or exceptions to be thrown on
                        // invalid Char values.
                        Console.OutputEncoding <- UnicodeEncoding(not BitConverter.IsLittleEndian, false)
                        printfn "\nOutput encoding set to UTF-16"

                    with :? IOException ->
                        printfn "Output encoding set to UTF-8"
                        Console.OutputEncoding <- UTF8Encoding()
                else
                    printfn "The console encoding is %s (code page %i)" (Console.OutputEncoding.EncodingName)
                        (Console.OutputEncoding.CodePage)

                displayRange parsedArgs.rangeStart parsedArgs.rangeEnd
        with :? ArgumentException as ex -> Console.WriteLine(ex.Message)
    finally
        // Restore console environment.
        Console.OutputEncoding <- originalOutputEncoding
    0

// If the example is run with the command line
//       DisplayChars 0400 04FF true
// the example displays the Cyrillic character set as follows:
//       Output encoding set to UTF-16
//       00400  Ѐ  Ё  Ђ  Ѓ - Є  Ѕ  І  Ї -- Ј  Љ  Њ  Ћ - Ќ  Ѝ  Ў  Џ
//       00410  А  Б  В  Г - Д  Е  Ж  З -- И  Й  К  Л - М  Н  О  П
//       00420  Р  С  Т  У - Ф  Х  Ц  Ч -- Ш  Щ  Ъ  Ы - Ь  Э  Ю  Я
//       00430  а  б  в  г - д  е  ж  з -- и  й  к  л - м  н  о  п
//       00440  р  с  т  у - ф  х  ц  ч -- ш  щ  ъ  ы - ь  э  ю  я
//       00450  ѐ  ё  ђ  ѓ - є  ѕ  і  ї -- ј  љ  њ  ћ - ќ  ѝ  ў  џ
//       00460  Ѡ  ѡ  Ѣ  ѣ - Ѥ  ѥ  Ѧ  ѧ -- Ѩ  ѩ  Ѫ  ѫ - Ѭ  ѭ  Ѯ  ѯ
//       00470  Ѱ  ѱ  Ѳ  ѳ - Ѵ  ѵ  Ѷ  ѷ -- Ѹ  ѹ  Ѻ  ѻ - Ѽ  ѽ  Ѿ  ѿ
//       00480  Ҁ  ҁ  ҂  ҃ - ҄  ҅  ҆  ҇ -- ҈  ҉  Ҋ  ҋ - Ҍ  ҍ  Ҏ  ҏ
//       00490  Ґ  ґ  Ғ  ғ - Ҕ  ҕ  Җ  җ -- Ҙ  ҙ  Қ  қ - Ҝ  ҝ  Ҟ  ҟ
//       004a0  Ҡ  ҡ  Ң  ң - Ҥ  ҥ  Ҧ  ҧ -- Ҩ  ҩ  Ҫ  ҫ - Ҭ  ҭ  Ү  ү
//       004b0  Ұ  ұ  Ҳ  ҳ - Ҵ  ҵ  Ҷ  ҷ -- Ҹ  ҹ  Һ  һ - Ҽ  ҽ  Ҿ  ҿ
//       004c0  Ӏ  Ӂ  ӂ  Ӄ - ӄ  Ӆ  ӆ  Ӈ -- ӈ  Ӊ  ӊ  Ӌ - ӌ  Ӎ  ӎ  ӏ
//       004d0  Ӑ  ӑ  Ӓ  ӓ - Ӕ  ӕ  Ӗ  ӗ -- Ә  ә  Ӛ  ӛ - Ӝ  ӝ  Ӟ  ӟ
//       004e0  Ӡ  ӡ  Ӣ  ӣ - Ӥ  ӥ  Ӧ  ӧ -- Ө  ө  Ӫ  ӫ - Ӭ  ӭ  Ӯ  ӯ
//       004f0  Ӱ  ӱ  Ӳ  ӳ - Ӵ  ӵ  Ӷ  ӷ -- Ӹ  ӹ  Ӻ  ӻ - Ӽ  ӽ  Ӿ  ӿ

Общие операции

Класс Console содержит следующие методы чтения входных и выходных данных консоли:

  • Перегрузки ReadKey метода считывают отдельный символ.

  • Метод ReadLine считывает всю строку входных данных.

  • Метод Write перегружает экземпляр типа значения, массив символов или набор объектов в форматированную или неформатированную строку, а затем записывает ее в консоль.

  • Параллельный WriteLine набор перегрузок метода выводит ту же строку, что и Write перегрузки, но также добавляет строку завершения строки.

Класс Console также содержит методы и свойства для выполнения следующих операций:

  • Получение или установка размера буфера экрана. Свойства BufferHeight позволяют BufferWidth получить или задать высоту и ширину буфера соответственно, а SetBufferSize метод позволяет задать размер буфера в одном вызове метода.

  • Получение или установка размера окна консоли. WindowWidth Свойства WindowHeight позволяют получить или задать высоту и ширину окна соответственно, а SetWindowSize метод позволяет задать размер окна в одном вызове метода.

  • Получение или установка размера курсора. Свойство CursorSize задает высоту курсора в ячейке символов.

  • Получение или установка положения окна консоли относительно буфера экрана. WindowLeft Свойства WindowTop позволяют получить или задать верхнюю строку и крайний левый столбец буфера экрана, который отображается в окне консоли, и SetWindowPosition метод позволяет задать эти значения в одном вызове метода.

  • Получение или задание положения курсора путем получения или задания CursorTop свойств CursorLeft или задания положения курсора путем вызова SetCursorPosition метода.

  • Переместите или очистите данные в буфере экрана, вызвав MoveBufferArea метод или Clear метод.

  • Получение или настройка цветов переднего плана и фона с помощью ForegroundColor свойств BackgroundColor или сброс фона и переднего плана до их цветов по умолчанию путем вызова ResetColor метода.

  • Воспроизведение звука звукового сигнала через динамик консоли путем вызова Beep метода.

основные заметки .NET

В платформа .NET Framework на рабочем столе Console класс использует кодирование, возвращаемое GetConsoleCP и GetConsoleOutputCPобычно кодирование кодовой страницы. Например, код в системах с языком и региональными параметрами (США), кодовая страница 437 — это кодировка, используемая по умолчанию. Однако .NET Core может сделать доступным только ограниченное подмножество этих кодировок. В этом случае Encoding.UTF8 используется в качестве кодировки по умолчанию для консоли.

Если приложение зависит от определенных кодировок кодовой страницы, вы по-прежнему можете сделать их доступными, выполнив следующие действия перед вызовом любых Console методов:

  1. Добавьте в проект ссылку на сборку System.Text.Encoding.CodePages.dll.

  2. Получите объект EncodingProvider из свойства CodePagesEncodingProvider.Instance.

  3. Передайте объект EncodingProvider в метод Encoding.RegisterProvider, чтобы сделать доступными дополнительные кодировки, поддерживаемые поставщиком кодировки.

Затем Console класс будет автоматически использовать системную кодировку по умолчанию, а не UTF8, если вы зарегистрировали поставщик кодирования перед вызовом любых Console выходных методов.

Свойства

BackgroundColor

Возвращает или задает цвет фона консоли.

BufferHeight

Возвращает или задает высоту буферной области.

BufferWidth

Возвращает или задает ширину буферной области.

CapsLock

Возвращает значение, указывающее, включен или отключен режим CAPS LOCK клавиатуры.

CursorLeft

Возвращает или задает позицию столбца курсора в буферной области.

CursorSize

Возвращает или задает высоту курсора в символьной ячейке.

CursorTop

Возвращает или задает позицию строки курсора в буферной области.

CursorVisible

Возвращает или задает значение, указывающее, видим ли курсор.

Error

Возвращает стандартный выходной поток сообщений об ошибках.

ForegroundColor

Возвращает или задает цвет фона консоли.

In

Возвращает стандартный входной поток.

InputEncoding

Возвращает или задает кодировку консоли, используемую при чтении входных данных.

IsErrorRedirected

Получает значение, показывающее, был ли перенаправлен выходной поток ошибок от стандартного потока ошибок.

IsInputRedirected

Получает значение, показывающее, был ли перенаправлены ли входные данные от стандартного входного потока.

IsOutputRedirected

Получает значение, показывающее, был ли перенаправлены выходные данные от стандартного выходного потока.

KeyAvailable

Возвращает или задает значение, указывающее, доступно ли нажатие клавиши во входном потоке.

LargestWindowHeight

Возвращает максимальное число строк окна консоли с учетом текущего шрифта и разрешения экрана.

LargestWindowWidth

Возвращает максимальное число столбцов окна консоли с учетом текущего шрифта и разрешения экрана.

NumberLock

Возвращает значение, указывающее, включен или отключен режим NUM LOCK клавиатуры.

Out

Возвращает стандартный выходной поток.

OutputEncoding

Получает или задает кодировку консоли, используемую при записи выходных данных.

Title

Возвращает или задает заголовок для отображения в строке заголовка консоли.

TreatControlCAsInput

Получает или задает значение, указывающее, интерпретируется ли комбинация клавиши-модификатора Control и клавиши консоли C (Ctrl+C) как обычный ввод или как прерывание, которое обрабатывается операционной системой.

WindowHeight

Возвращает или задает высоту области окна консоли.

WindowLeft

Возвращает или задает позицию левого края области окна консоли относительно буфера экрана.

WindowTop

Возвращает или задает позицию верхнего края области окна консоли относительно буфера экрана.

WindowWidth

Возвращает или задает ширину окна консоли.

Методы

Beep()

Воспроизводит звуковой сигнал через динамик консоли.

Beep(Int32, Int32)

Воспроизводит звуковой сигнал заданной частоты и длительности через динамик консоли.

Clear()

Удаляет из буфера консоли и ее окна отображаемую информацию.

GetCursorPosition()

Возвращает положение курсора.

MoveBufferArea(Int32, Int32, Int32, Int32, Int32, Int32)

Копирует заданную исходную область буфера экрана в заданную область назначения.

MoveBufferArea(Int32, Int32, Int32, Int32, Int32, Int32, Char, ConsoleColor, ConsoleColor)

Копирует заданную исходную область буфера экрана в заданную область назначения.

OpenStandardError()

Получает стандартный поток сообщений об ошибках.

OpenStandardError(Int32)

Получает стандартный поток сообщений об ошибках, для которого установлен заданный размер буфера.

OpenStandardInput()

Получает стандартный входной поток.

OpenStandardInput(Int32)

Получает стандартный входной поток, для которого установлен заданный размер буфера.

OpenStandardOutput()

Получает стандартный выходной поток.

OpenStandardOutput(Int32)

Получает стандартный выходной поток, для которого установлен заданный размер буфера.

Read()

Читает следующий символ из стандартного входного потока.

ReadKey()

Получает следующий нажатый пользователем символ или функциональную клавишу. Нажатая клавиша отображается в окне консоли.

ReadKey(Boolean)

Получает следующий нажатый пользователем символ или функциональную клавишу. Нажатая клавиша может быть отображена в окне консоли.

ReadLine()

Считывает следующую строку символов из стандартного входного потока.

ResetColor()

Устанавливает для цветов фона и текста консоли их значения по умолчанию.

SetBufferSize(Int32, Int32)

Устанавливает заданные значения высоты и ширины буферной области экрана.

SetCursorPosition(Int32, Int32)

Устанавливает положение курсора.

SetError(TextWriter)

Присваивает свойству Error указанный объект TextWriter.

SetIn(TextReader)

Присваивает свойству In указанный объект TextReader.

SetOut(TextWriter)

Присваивает свойству Out указанный объект TextWriter.

SetWindowPosition(Int32, Int32)

Задает позицию окна консоли относительно буфера экрана.

SetWindowSize(Int32, Int32)

Устанавливает заданные значения высоты и ширины окна консоли.

Write(Boolean)

Записывает текстовое представление заданного логического значения в стандартный выходной поток.

Write(Char)

Записывает значение заданного знака Юникода в стандартный выходной поток.

Write(Char[])

Записывает заданный массив знаков Юникода в стандартный выходной поток.

Write(Char[], Int32, Int32)

Записывает заданный дочерний массив знаков Юникода в стандартный выходной поток.

Write(Decimal)

Записывает текстовое представление заданного значения Decimal в стандартный выходной поток.

Write(Double)

Записывает текстовое представление заданного значения двойной точности с плавающей запятой в стандартный выходной поток.

Write(Int32)

Записывает текстовое представление заданного 32-битового целого числа со знаком в стандартный поток вывода.

Write(Int64)

Записывает текстовое представление заданного 64-битового целого числа со знаком в стандартный поток вывода.

Write(Object)

Записывает текстовое представление заданного объекта в стандартный выходной поток.

Write(Single)

Записывает текстовое представление заданного значения одинарной точности с плавающей запятой в стандартный выходной поток.

Write(String)

Записывает заданное строковое значение в стандартный выходной поток.

Write(String, Object)

Записывает текстовое представление заданного объекта в стандартный выходной поток, используя заданные сведения о форматировании.

Write(String, Object, Object)

Записывает текстовые представления заданных объектов в стандартный выходной поток, используя заданные сведения о форматировании.

Write(String, Object, Object, Object)

Записывает текстовые представления заданных объектов в стандартный выходной поток, используя заданные сведения о форматировании.

Write(String, Object, Object, Object, Object)

Записывает текстовое представление заданных объектов и список параметров переменной длины в стандартный выходной поток, используя заданные сведения о форматировании.

Write(String, Object[])

Записывает текстовое представление заданного массива объектов в стандартный выходной поток, используя заданные сведения о форматировании.

Write(UInt32)

Записывает текстовое представление заданного 32-битового целого числа без знака в стандартный выходной поток.

Write(UInt64)

Записывает текстовое представление заданного 64-битового целого числа без знака в стандартный выходной поток.

WriteLine()

Записывает текущий признак конца строки в стандартный выходной поток.

WriteLine(Boolean)

Записывает текстовое представление заданного логического значения с текущим признаком конца строки в стандартный выходной поток.

WriteLine(Char)

Записывает заданный знак Юникода, за которым следует текущий признак конца строки, в стандартный выходной поток.

WriteLine(Char[])

Записывает заданный массив знаков Юникода, за которым следует текущий признак конца строки, в стандартный выходной поток.

WriteLine(Char[], Int32, Int32)

Записывает заданный подмассив знаков Юникода, за которым следует текущий признак конца строки, в стандартный выходной поток.

WriteLine(Decimal)

Записывает текстовое представление указанного значения Decimal, за которым следует текущий знак завершения строки, в стандартный выходной поток.

WriteLine(Double)

Записывает текстовое представление заданного значения двойной точности с плавающей запятой, за которым следует признак конца строки, в стандартный выходной поток.

WriteLine(Int32)

Записывает текстовое представление заданного 32-битового целого числа со знаком, за которым следует текущий знак завершения строки, в стандартный выходной поток.

WriteLine(Int64)

Записывает текстовое представление заданного 64-битового целого числа со знаком, за которым следует текущий знак завершения строки, в стандартный поток вывода.

WriteLine(Object)

Записывает текстовое представление заданного объекта, за которым следует текущий признак конца строки, в стандартный выходной поток.

WriteLine(Single)

Записывает текстовое представление заданного значения одинарной точности с плавающей запятой, за которым следует признак конца строки, в стандартный выходной поток.

WriteLine(String)

Записывает заданное строковое значение, за которым следует текущий признак конца строки, в стандартный выходной поток.

WriteLine(String, Object)

Записывает текстовое представление заданного объекта, за которым следует текущий признак конца строки, в стандартный выходной поток с использованием заданных сведений о форматировании.

WriteLine(String, Object, Object)

Записывает текстовые представления заданных объектов, за которыми следует текущий признак конца строки, в стандартный выходной поток с использованием заданных сведений о форматировании.

WriteLine(String, Object, Object, Object)

Записывает текстовые представления заданных объектов, за которыми следует текущий признак конца строки, в стандартный выходной поток с использованием заданных сведений о форматировании.

WriteLine(String, Object, Object, Object, Object)

Записывает текстовые представления заданных объектов и список параметров переменной длины, за которыми следует текущий признак конца строки, в стандартный выходной поток с использованием заданных сведений о форматировании.

WriteLine(String, Object[])

Записывает текстовые представления заданного массива объектов, за которым следует текущий признак конца строки, в стандартный выходной поток с использованием заданных сведений о форматировании.

WriteLine(UInt32)

Записывает текстовое представление заданного 32-битового целого числа без знака, за которым следует текущий признак конца строки, в стандартный выходной поток.

WriteLine(UInt64)

Записывает текстовое представление заданного 64-битового целого числа без знака, за которым следует текущий признак конца строки, в стандартный выходной поток.

События

CancelKeyPress

Возникает при одновременном нажатии клавиши-модификатора Control (Ctrl) и либо клавиши консоли C (C), либо клавиши Break (Ctrl+C или Ctrl+Break).

Применяется к

Потокобезопасность

Данный тип потокобезопасен.