C# 从控制台读取unicode

C# 从控制台读取unicode,c#,.net,encoding,console,C#,.net,Encoding,Console,我试图从C#中的控制台读取unicode字符串,为了举例,让我们使用他的一个: c:\SVN\D³ebugger\src\fvааааimk_\Program.cs 起初我只是尝试Console.ReadLine(),它返回了我c:\SVN\D3ebugger\src\??\Program.cs 我尝试将Console.inpunecoding设置为UTF8,就像这样Console.inpunecoding=Encoding.UTF8,但这返回了我c:\SVN\D³ebugger\src\???

我试图从C#中的控制台读取unicode字符串,为了举例,让我们使用他的一个:

c:\SVN\D³ebugger\src\fvааааimk_\Program.cs

起初我只是尝试
Console.ReadLine()
,它返回了我
c:\SVN\D3ebugger\src\??\Program.cs

我尝试将Console.inpunecoding设置为UTF8,就像这样
Console.inpunecoding=Encoding.UTF8
,但这返回了我
c:\SVN\D³ebugger\src\???\Program.cs
,基本上弄乱了字符串的西里尔字母部分

所以随机绊倒我试着这样设置编码,
Console.inpunecoding=encoding.GetEncoding(1251)
返回
c:\SVN\D?ebugger\src\f5аааааimk_\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);
这对于非unicode字符串来说很好,但是,当我试图让它读取我的示例字符串时,应用程序崩溃了。我试图告诉VisualStudio打破所有异常(包括本机异常),但应用程序仍然会崩溃

我还在微软的Connect中发现了一个公开的bug,它似乎表明现在不可能从控制台的输入流中读取Unicode

值得注意的是,即使与我的问题没有严格的关系,如果Console.outputeneconding设置为UTF8,Console.WriteLine也可以很好地打印这个字符串

谢谢大家!

更新1 我正在寻找.NET3.5的解决方案

更新2
使用我使用过的完整本机代码进行了更新。

这在针对.NET 4客户端配置文件时似乎效果不错,但不幸的是,在针对.NET 3.5客户端配置文件时效果不佳。确保将console字体更改为Lucida console。
正如@jcl所指出的,尽管我的目标是.NET4,但这只是因为我安装了.NET4.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);
            }
        }
    }
}

下面是一个在.NET 3.5客户端中完全可用的版本:

类程序
{
[DllImport(“kernel32.dll”,SetLastError=true)]
静态外部IntPtr GetStdHandle(intnstdhandle);
[DllImport(“kernel32.dll”)]
静态外部bool ReadConsoleW(IntPtr hConsoleInput,[Out]字节[]
lpBuffer,uint nNumberOfCharsToRead,out uint lpNumberOfCharsRead,
IntPtr(保留);
公共静态IntPtr GetWin32InputHandle()
{
const int STD_INPUT_HANDLE=-10;
IntPtr inHandle=GetStdHandle(标准输入句柄);
在处理中返回;
}
公共静态字符串读取行()
{
const int bufferSize=1024;
var buffer=新字节[bufferSize];
uint charsRead=0;
ReadConsoleW(GetWin32InputHandle(),buffer,bufferSize,out charsRead,(IntPtr)0);
//-2以删除结尾\n\r\n
int nc=((int)charsRead-2)*2;
var b=新字节[nc];
对于(变量i=0;i

您是否使用.NET 4.5?它在.NET4.0中不起作用。行
Console.inpunecoding=Encoding.Unicode引发异常:“IOException-参数不正确。”我确实安装了VS11测试版和.NET 4.5测试版。但是,控制台应用程序使用VS 2010和.NET 4客户端配置文件工作。我使用的是Windows 7 x64 SP1。我可以确认,在针对.NET 3.5客户端配置文件时,我会遇到与您相同的异常。除非您安装了.NET 4.5,否则它肯定无法在.NET 4.0上工作。您的目标应用程序正在使用mscorlib的更新版本(奇怪的是,Microsoft在.NET 4.5的开发者预览中没有更改版本号,这就是为什么即使您的目标是4.0,它也会使用它),这实际上会显式地检查Unicode代码页是否不调用SetConsoleECP。该检查未包含在4.0中的常规mscorlib.dll中,这就是为什么它会引发IOException(当SetConsoleECP失败时它会这样做)。您好,我正在运行这是一个从应用程序,而且它似乎不适用于meIs使用命名管道而不是控制台是否可能/可以接受?如果我找不到解决方案,那么我可能会这样做…如果需要大字符串,请更改ReadLine()中的bufferSize。请注意,缓冲区占用的字节数是字符数的两倍。另外,如果您不介意使用Linq,可以使用:
varb=buffer.Take(nc.ToArray()而不是那个丑陋的For循环。它工作得很好,谢谢!不过,我做了一些非常类似的事情(使用ReadConsoleView),根本不起作用。我会检查我做错了什么并进行更新。之后你可能没有转换成UTF8。可能输入是正确的,但输出不是(只是猜测)。多亏了你的回答,我发现了我做错了什么,并进行了相应的编辑。它曾经是
new StringBuilder()
,它对ANSI很好,但对Unicode却崩溃了。现在,当我用初始大小初始化它时-
newstringbuilder(nNumberOfCharsToRead)
。再次感谢!