Classe System.Console

Cet article vous offre des remarques complémentaires à la documentation de référence pour cette API.

La console est une fenêtre de système d’exploitation où les utilisateurs interagissent avec le système d’exploitation ou avec une application console basée sur du texte en entrant une entrée de texte via le clavier de l’ordinateur et en lisant la sortie du texte à partir du terminal informatique. Par exemple, dans le système d’exploitation Windows, la console est appelée fenêtre d’invite de commandes et accepte les commandes MS-DOS. La Console classe fournit une prise en charge de base pour les applications qui lisent des caractères et écrivent des caractères dans la console.

Flux d’E/S de console

Quand une application console démarre, le système d’exploitation associe automatiquement trois flux d’E/S à la console : flux d’entrée standard, flux de sortie standard et flux de sortie d’erreur standard. Votre application peut lire les entrées utilisateur à partir du flux d’entrée standard ; écrire des données normales dans le flux de sortie standard ; et écrire des données d’erreur dans le flux de sortie d’erreur standard. Ces flux sont présentés à votre application en tant que valeurs des propriétés et Console.ErrorConsole.Outdes Console.Inpropriétés.

Par défaut, la valeur de la In propriété est un System.IO.TextReader objet qui représente le clavier et les valeurs des propriétés et Error des Out objets qui System.IO.TextWriter représentent une fenêtre de console. Toutefois, vous pouvez définir ces propriétés sur des flux qui ne représentent pas la fenêtre de console ou le clavier ; Par exemple, vous pouvez définir ces propriétés sur des flux qui représentent des fichiers. Pour rediriger l’entrée standard, la sortie standard ou le flux d’erreur standard, appelez respectivement le ou Console.SetOutConsole.SetError la Console.SetInméthode. Les opérations d’E/S qui utilisent ces flux sont synchronisées, ce qui signifie que plusieurs threads peuvent lire ou écrire dans les flux. Cela signifie que les méthodes qui sont généralement asynchrones, telles que TextReader.ReadLineAsync, s’exécutent de manière synchrone si l’objet représente un flux de console.

Remarque

N’utilisez pas la classe pour afficher la Console sortie dans des applications sans assistance, telles que les applications serveur. Les appels à des méthodes telles que Console.Write celles-ci Console.WriteLine n’ont aucun effet dans les applications gui.

Console Les membres de classe qui fonctionnent normalement lorsque le flux sous-jacent est dirigé vers une console peuvent lever une exception si le flux est redirigé, par exemple vers un fichier. Programmez votre application pour intercepter les System.IO.IOException exceptions si vous redirigez un flux standard. Vous pouvez également utiliser les propriétés et IsInputRedirectedIsErrorRedirected les IsOutputRedirectedpropriétés pour déterminer si un flux standard est redirigé avant d’effectuer une opération qui lève une System.IO.IOException exception.

Il est parfois utile d’appeler explicitement les membres des objets de flux représentés par les propriétés et OutError les Inpropriétés. Par exemple, par défaut, la Console.ReadLine méthode lit l’entrée à partir du flux d’entrée standard. De même, la Console.WriteLine méthode écrit des données dans le flux de sortie standard, et les données sont suivies de la chaîne d’arrêt de ligne par défaut, qui est disponible à l’adresse Environment.NewLine. Toutefois, la Console classe ne fournit pas de méthode correspondante pour écrire des données dans le flux de sortie d’erreur standard, ou une propriété pour modifier la chaîne d’arrêt de ligne pour les données écrites dans ce flux.

Vous pouvez résoudre ce problème en définissant la TextWriter.NewLine propriété de l’objet ou Error la Out propriété sur une autre chaîne d’arrêt de ligne. Par exemple, l’instruction C# suivante définit la chaîne d’arrêt de ligne pour le flux de sortie d’erreur standard sur deux séquences de retour chariot et de flux de ligne :

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

Vous pouvez ensuite appeler explicitement la WriteLine méthode de l’objet de flux de sortie d’erreur, comme dans l’instruction C# suivante :

Console.Error.WriteLine();

Mémoire tampon d’écran et fenêtre de console

Deux fonctionnalités étroitement liées à la console sont la mémoire tampon d’écran et la fenêtre de console. Le texte est en fait lu ou écrit dans des flux appartenant à la console, mais semble être lu ou écrit dans une zone appartenant à la console appelée mémoire tampon d’écran. La mémoire tampon d’écran est un attribut de la console et est organisée sous la forme d’une grille rectangulaire de lignes et de colonnes où chaque intersection de grille ou cellule de caractère peut contenir un caractère. Chaque caractère a sa propre couleur de premier plan, et chaque cellule de caractère a sa propre couleur d’arrière-plan.

La mémoire tampon d’écran est vue par le biais d’une région rectangulaire appelée fenêtre de console. La fenêtre de console est un autre attribut de la console ; il n’est pas la console elle-même, qui est une fenêtre de système d’exploitation. La fenêtre de console est organisée dans les lignes et les colonnes, est inférieure ou égale à la taille de la mémoire tampon d’écran et peut être déplacée pour afficher différentes zones de la mémoire tampon d’écran sous-jacente. Si la mémoire tampon d’écran est supérieure à la fenêtre de console, la console affiche automatiquement des barres de défilement afin que la fenêtre de console puisse être repositionnée sur la zone de mémoire tampon de l’écran.

Un curseur indique la position de la mémoire tampon d’écran où le texte est actuellement lu ou écrit. Le curseur peut être masqué ou rendu visible, et sa hauteur peut être modifiée. Si le curseur est visible, la position de la fenêtre de console est déplacée automatiquement afin que le curseur soit toujours affiché.

L’origine des coordonnées de cellule de caractères dans la mémoire tampon d’écran est le coin supérieur gauche, et les positions du curseur et de la fenêtre de console sont mesurées par rapport à cette origine. Utilisez des index de base zéro pour spécifier des positions ; autrement dit, spécifiez la ligne la plus haute en tant que ligne 0 et la colonne la plus à gauche en tant que colonne 0. La valeur maximale des index de ligne et de colonne est Int16.MaxValue.

Prise en charge Unicode de la console

En général, la console lit l’entrée et écrit la sortie à l’aide de la page de codes de la console actuelle, que les paramètres régionaux système définissent par défaut. Une page de codes ne peut gérer qu’un sous-ensemble de caractères Unicode disponibles. Par conséquent, si vous essayez d’afficher des caractères qui ne sont pas mappés par une page de codes particulière, la console ne pourra pas afficher tous les caractères ou les représenter avec précision. L'exemple de code suivant illustre ce problème. Il tente d’afficher les caractères de l’alphabet cyrillique de U+0410 à U+044F à la console. Si vous exécutez l’exemple sur un système qui utilise la page de codes de la console 437, chaque caractère est remplacé par un point d’interrogation ( ?), car les caractères cyrilliques ne correspondent pas aux caractères de la page de codes 437.

using System;

public class Example3
{
    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
//
//    ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?
//    ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?
//    ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?

Outre la prise en charge des pages de code, la Console classe prend en charge l’encodage UTF-8 avec la UTF8Encoding classe. À compter de .NET Framework 4.5, la classe prend également en charge l’encodage Console UTF-16 avec la UnicodeEncoding classe. Pour afficher des caractères Unicode dans la console. vous définissez la propriété sur l’une OutputEncoding ou l’autre UTF8Encoding ou UnicodeEncoding.

La prise en charge des caractères Unicode nécessite que l’encodeur reconnaisse un caractère Unicode particulier, et nécessite également une police qui a les glyphes nécessaires pour afficher ce caractère. Pour afficher correctement des caractères Unicode dans la console, la police de la console doit être définie sur une police non raster ou TrueType telle que Consolas ou Lucida Console. L’exemple suivant montre comment modifier par programmation la police d’une police raster vers La console Lucida.

using System;
using System.Runtime.InteropServices;

public class Example2
{
    [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 Example5
    ' <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

Toutefois, les polices TrueType ne peuvent afficher qu’un sous-ensemble de glyphes. Par exemple, la police Lucida Console affiche uniquement 643 des 64 000 caractères disponibles d’U+0021 à U+FB022. Pour afficher les caractères pris en charge par une police particulière, ouvrez l’applet Polices dans Panneau de configuration, choisissez l’option Rechercher un caractère et choisissez la police dont vous souhaitez examiner le jeu de caractères dans laliste des polices de la fenêtre Mappage de caractères.

Windows utilise la liaison de polices pour afficher des glyphes qui ne sont pas disponibles dans une police particulière. Pour plus d’informations sur la liaison de polices pour afficher des jeux de caractères supplémentaires, consultez La globalisation pas à pas : polices. Les polices liées sont définies dans la sous-clé HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink\SystemLink du Registre. Chaque entrée associée à cette sous-clé correspond au nom d’une police de base, et sa valeur est un tableau de chaînes qui définit les fichiers de police et les polices liées à la police de base. Chaque membre du tableau définit une police liée et prend le formulaire font-file-name,font-name. L’exemple suivant montre comment définir par programmation une police liée nommée SimSun trouvée dans un fichier de police nommé simsun.ttc qui affiche des caractères Han simplifiés.

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 Example2
    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)) Then
                ' 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()

La prise en charge Unicode de la console présente les limitations suivantes :

  • L’encodage UTF-32 n’est pas pris en charge. Les seuls encodages Unicode pris en charge sont UTF-8 et UTF-16, qui sont représentés respectivement par les classes et UnicodeEncoding les UTF8Encoding classes.

  • La sortie bidirectionnelle n’est pas prise en charge.

  • L’affichage de caractères en dehors du plan multilingue de base (autrement dit, des paires de substitution) n’est pas pris en charge, même s’ils sont définis dans un fichier de police lié.

  • L’affichage de caractères dans des scripts complexes n’est pas pris en charge.

  • La combinaison de séquences de caractères (autrement dit, des caractères constitués d’un caractère de base et d’un ou plusieurs caractères combinés) s’affichent sous forme de caractères distincts. Pour contourner cette limitation, vous pouvez normaliser la chaîne à afficher en appelant la String.Normalize méthode avant d’envoyer la sortie à la console. Dans l’exemple suivant, une chaîne qui contient la séquence de caractères combinée U+0061 U+0308 s’affiche dans la console sous la forme de deux caractères avant la normalisation de la chaîne de sortie et en tant que caractère unique après l’appel de la String.Normalize méthode.

    using System;
    using System.IO;
    
    public class Example1
    {
        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 Example3
        Public Sub Main()
            Dim chars() As Char = {ChrW(&H61), ChrW(&H308)}
    
            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"
    //       ä
    

    La normalisation est une solution viable uniquement si la norme Unicode pour le caractère inclut un formulaire prédéfini qui correspond à une séquence de caractères combinée particulière.

  • Si une police fournit un glyphe pour un point de code dans la zone d’utilisation privée, ce glyphe s’affiche. Toutefois, étant donné que les caractères de la zone d’utilisation privée sont spécifiques à l’application, il se peut que ce ne soit pas le glyphe attendu.

L’exemple suivant affiche une plage de caractères Unicode dans la console. L’exemple accepte trois paramètres de ligne de commande : le début de la plage à afficher, la fin de la plage à afficher et l’utilisation de l’encodage de console actuel (false) ou uTF-16 (true). Il part du principe que la console utilise une police 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  Ӱ  ӱ  Ӳ  ӳ - Ӵ  ӵ  Ӷ  ӷ -- Ӹ  ӹ  Ӻ  ӻ - Ӽ  ӽ  Ӿ  ӿ

Opérations courantes

La Console classe contient les méthodes suivantes pour lire les entrées de console et écrire la sortie de la console :

  • Les surcharges de la ReadKey méthode lisent un caractère individuel.

  • La ReadLine méthode lit une ligne d’entrée entière.

  • La Write méthode surcharge une instance d’un type valeur, un tableau de caractères ou un ensemble d’objets en chaîne mise en forme ou non mise en forme, puis écrit cette chaîne dans la console.

  • Un ensemble parallèle de surcharges de WriteLine méthode génère la même chaîne que les Write surcharges, mais ajoute également une chaîne d’arrêt de ligne.

La Console classe contient également des méthodes et des propriétés pour effectuer les opérations suivantes :

  • Obtenez ou définissez la taille de la mémoire tampon d’écran. BufferWidth Les BufferHeight propriétés vous permettent d’obtenir ou de définir la hauteur et la largeur de la mémoire tampon, respectivement, et la SetBufferSize méthode vous permet de définir la taille de la mémoire tampon dans un appel de méthode unique.

  • Obtenez ou définissez la taille de la fenêtre de console. WindowWidth Les WindowHeight propriétés vous permettent d’obtenir ou de définir respectivement la hauteur et la largeur de la fenêtre, et la SetWindowSize méthode vous permet de définir la taille de la fenêtre dans un appel de méthode unique.

  • Obtenez ou définissez la taille du curseur. La CursorSize propriété spécifie la hauteur du curseur dans une cellule de caractère.

  • Obtenez ou définissez la position de la fenêtre de console par rapport à la mémoire tampon d’écran. WindowLeft Les WindowTop propriétés vous permettent d’obtenir ou de définir la ligne supérieure et la colonne la plus à gauche de la mémoire tampon d’écran qui apparaît dans la fenêtre de console, et la SetWindowPosition méthode vous permet de définir ces valeurs dans un appel de méthode unique.

  • Obtenez ou définissez la position du curseur en obtenant ou en définissant les propriétés et CursorLeft les CursorTop propriétés, ou définissez la position du curseur en appelant la SetCursorPosition méthode.

  • Déplacez ou effacez les données dans la mémoire tampon d’écran en appelant ou MoveBufferAreaClear méthode.

  • Obtenez ou définissez les couleurs de premier plan et d’arrière-plan à l’aide des propriétés et BackgroundColor de l’arrière-planForegroundColor, ou réinitialisez l’arrière-plan et le premier plan sur leurs couleurs par défaut en appelant la ResetColor méthode.

  • Lire le son d’un bip via le haut-parleur de console en appelant la Beep méthode.

Notes .NET Core

Dans .NET Framework sur le bureau, la Console classe utilise l’encodage retourné par GetConsoleCP et GetConsoleOutputCP, qui est généralement un encodage de page de codes. Par exemple, sur les systèmes dont la culture est anglaise (États-Unis), la page de codes 437 est l’encodage utilisé par défaut. Toutefois, .NET Core ne peut rendre disponible qu’un sous-ensemble limité de ces encodages. Là où il s’agit du cas, Encoding.UTF8 est utilisé comme encodage par défaut pour la console.

Si votre application dépend des encodages de page de codes spécifiques, vous pouvez toujours les rendre disponibles en procédant comme suit avant d’appeler Console des méthodes :

  1. Récupérez l’objet EncodingProvider de la CodePagesEncodingProvider.Instance propriété.

  2. Transmettez l’objet EncodingProvider à la Encoding.RegisterProvider méthode pour rendre les encodages supplémentaires pris en charge par le fournisseur d’encodage.

La Console classe utilise ensuite automatiquement l’encodage système par défaut plutôt que UTF8, à condition que vous ayez inscrit le fournisseur d’encodage avant d’appeler des Console méthodes de sortie.

Exemples

L’exemple suivant montre comment lire des données et écrire des données dans les flux d’entrée et de sortie standard. Notez que ces flux peuvent être redirigés à l’aide des méthodes et SetOut des SetIn méthodes.

using System;

public class Example4
{
    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 Example4
    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!