从控制台读取unicode

Vit*_*lyB 15 .net c# console encoding

我试图从C#中的控制台读取unicode字符串,例如,让我使用他的:

C:\ SVN \D³ebugger的\ src \виталик\的Program.cs

起初我只是试着Console.ReadLine()回复了我c:\SVN\D3ebugger\src\???????\Program.cs

我已经尝试将Console.InputEncoding设置为UTF8,Console.InputEncoding = Encoding.UTF8但是返回了我c:\SVN\D³ebugger\src\???????\Program.cs,基本上将字符串的Cyrillic部分弄糟了.

所以随机磕磕绊绊,我试图设置这样的编码,Console.InputEncoding = Encoding.GetEncoding(1251);这回来了c:\SVN\D?ebugger\src\???????\Program.cs,这次破坏了³角色.

此时似乎通过切换InputStream的编码,我一次只能获得一种语言.

我也尝试过本地人做这样的事情:

// Code
public static string ReadLine()
{
    const uint nNumberOfCharsToRead = 1024;
    StringBuilder buffer = new StringBuilder();

    uint charsRead = 0;
    bool result = ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), buffer, nNumberOfCharsToRead, out charsRead, (IntPtr)0);

    // Return the input minus the newline character
    if (result && charsRead > 1) return buffer.ToString(0, (int)charsRead - 1);
    return string.Empty;
}

// Extern definitions

    [DllImport("Kernel32.DLL", ExactSpelling = true)]
    internal static extern IntPtr GetStdHandle(int nStdHandle);

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
    static extern bool ReadConsoleW(IntPtr hConsoleInput, [Out] StringBuilder lpBuffer, 
        uint nNumberOfCharsToRead, out uint lpNumberOfCharsRead, IntPtr lpReserved);
Run Code Online (Sandbox Code Playgroud)

这对于非unicode字符串工作正常,但是,当我试图让它读取我的示例字符串时,应用程序崩溃了.我试图告诉Visual Studio打破所有异常(包括本机异常),然而,应用程序仍然会崩溃.

我还在Microsoft的Connect中发现了这个开放的错误,似乎说现在不可能从控制台的InputStream中读取Unicode.

值得注意的是,即使与我的问题没有严格关联,如果Console.OutputEncoding设置为UTF8,Console.WriteLine也可以正常打印此字符串.

谢谢!

更新1

我正在寻找.NET 3.5的解决方案

更新2

更新了我使用的完整本机代码.

Phi*_*hil 11

这在目标.NET 4客户端配置文件时似乎工作正常,但遗憾的是在目标.NET 3.5客户端配置文件时没有.确保将控制台字体更改为Lucida Console.
正如@jcl所指出的,即使我已经针对.NET4,这只是因为我安装了.NET 4.5.

class Program
{
    private static void Main(string[] args)
    {
        Console.InputEncoding = Encoding.Unicode;
        Console.OutputEncoding = Encoding.Unicode;

        while (true)
        {
            string s = Console.ReadLine();

            if (!string.IsNullOrEmpty(s))
            {
                Debug.WriteLine(s);

                Console.WriteLine(s);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Jcl*_*Jcl 6

这是.NET 3.5 Client中一个完全可用的版本:

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

  [DllImport("kernel32.dll")]
  static extern bool ReadConsoleW(IntPtr hConsoleInput, [Out] byte[]
     lpBuffer, uint nNumberOfCharsToRead, out uint lpNumberOfCharsRead,
     IntPtr lpReserved);

  public static IntPtr GetWin32InputHandle()
  {
    const int STD_INPUT_HANDLE = -10;
    IntPtr inHandle = GetStdHandle(STD_INPUT_HANDLE);
    return inHandle;
  }

  public static string ReadLine()
  {
    const int bufferSize = 1024;
    var buffer = new byte[bufferSize];

    uint charsRead = 0;

    ReadConsoleW(GetWin32InputHandle(), buffer, bufferSize, out charsRead, (IntPtr)0);
    // -2 to remove ending \n\r
    int nc = ((int)charsRead - 2) * 2;
    var b = new byte[nc];
    for (var i = 0; i < nc; i++)
      b[i] = buffer[i];

    var utf8enc = Encoding.UTF8;
    var unicodeenc = Encoding.Unicode;
    return utf8enc.GetString(Encoding.Convert(unicodeenc, utf8enc, b));
  }

  static void Main(string[] args)
  {
    Console.OutputEncoding = Encoding.UTF8;
    Console.Write("Input: ");
    var st = ReadLine();
    Console.WriteLine("Output: {0}", st);
  }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述