本文介绍了为什么CSC.EXE崩溃当我最后一次离开输出编码为UTF8?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我有,或遇到了一个非常奇怪的事情。



和我不知道别人有它的原因。



已经运行一行程序与此行的System.Console.WriteLine(System.Console.OutputEncoding.EncodingName); 我看到的编码是西欧(DOS)



精细



下面是一些代码页
名单 1200的Unicode 65001 UTF-8 视窗-1252西欧(Windows)中 850西欧DOS 来自的



说我写一个C锋利的程序编码更改为UTF-8

 类SDF 
{
静态无效的主要(字串[] args)
{
的System.Console.WriteLine(系统。 Console.OutputEncoding.EncodingName);
System.Console.OutputEncoding = System.Text.Encoding.GetEncoding(65001);
的System.Console.WriteLine(System.Console.OutputEncoding.EncodingName);
}
}



它的工作原理,它打印

 西欧(DOS)
的Unicode(UTF-8)

现在,当我再次运行CSC,CSC崩溃





我检查我的RAM为14个小时,8次传球,以MEMTEST。我跑的chkdsk我的硬盘驱动器,所有的罚款。而这绝对不是这些,这是一个编码的问题。
我知道,因为如果我打开了一个新的命令提示符,然后运行CSC,它不会崩溃。



所以运行升C程序,变化外壳使得下一次只运行CSC崩溃CSC本身,在大的方式。



如果我编译下面的代码,然后运行它,然后运行CSC,然后运行CSC,CSC或whatever.cs,我得到CSC崩溃。



所以关闭的命令提示符,打开一个新的。



这一次,实验意见,并在取消该计划的第二行



我觉得,如果第二行(更改代码页到850行(DOS西欧),是存在的,那么它也不会下一次我跑CSC崩溃。



而如果我注释掉的第二行,所以​​程序具有代码页/退出编码改为UTF-8,然后再下一次运行CSC,CSC崩溃。



//取消注释的最后一行,然后
/ /这个运行,但使得CSC崩溃下一次。

 类航空自卫队
{
静态无效的主要()
{

System.Console.OutputEncoding = System.Text.Encoding.UTF8; //输出为utf8
System.Console.OutputEncoding = System.Text.Encoding.GetEncoding(850);
}
}



我不是已经碰到东西的唯一的人像这样



虽然没有任何解释,发现那里的



我可以通过确保最后一行设置代码页850作为虽然我会解释这是对付它一个不充分的解决方案。



此外,我想知道这是否是与CSC一些问题,其他人有太多。或任何其他的解决方案。



添加



uuu1.cs

  // uuu1.cs 
级航空自卫队
{
静态无效的主要()
{

System.Console.InputEncoding = System.Text.Encoding.UTF8;
System.Console.OutputEncoding = System.Text.Encoding.UTF8;

//不是Unicode。 UTF8意味着然后重定向将工作

的System.Console.WriteLine(ჵ);

//尝试重定向太..

//并尝试检查CSC崩溃与否
//System.Console.OutputEncoding=System.Text.Encoding .GetEncoding(850);
//System.Console.InputEncoding = System.Text.Encoding.GetEncoding(850);
//问题是,被评论的时候,它打破了重定向



}
}

添加行/注释的最后几行,所以我必须



System.Console.OutputEncoding = System.Text.Encoding.GetEncoding(850);



将停止崩溃,但不充分的解决方案,因为例如..如果我想一个程序的输出重定向到一个文件,然后我需要UTF8所有从开始到结束,否则它不工作的方式。



这工作原理与代码页850行注释掉

  C:\blah> uuu1> R,R<&ENTER GT; 
C:\blah>类型R,R<&ENTER GT;
C:\blah>ჵ

如果我取消最后几行,从而改变了代码页850则肯定CSC不会崩溃就下运行,但重定向不能正常工作和RR不包含的字符。



新增2



汉的回答让我注意到触发这个错误

 <$的另一种方式C $ C> C:\Users\harvey\somecs3> CSC<&ENTER GT; 
微软(R)的Visual C#编译器版本4.0.30319.18408
适用于Microsoft(R).NET框架4.5
版权所有(C)微软公司。版权所有。

警告CS2008:没有指定的源文件
错误CS1562:没有源输出必须有输入/输出选项指定

C:\Users\harvey\ somecs3> CHCP 65001<&ENTER GT;
活动代码页:65001

C:\Users\harvey\somecs3> CSC<&ENTER GT; < - CRASH

C:\Users\harvey\somecs3>


解决方案

那么,你找到了这样一个错误的C#编译涉及当切换到UTF-8不必输出文本到控制台。它具有自诊断,以确保从UTF-16编码字符串到控制台输出的代码页转换工作正常,就猛地大红按钮,当它没有。堆栈跟踪看起来是这样的:

  CSC.EXE OnCriticalInternalError()+,位于0x4字节
CSC.EXE Con​​soleOutput! :: WideToConsole()+ 0xdc51字节
CSC.EXE!ConsoleOutput :: print_internal()+ 0x2c字节
CSC.EXE!ConsoleOutput ::打印()+ 0x80的字节
CSC.EXE! ConsoleOutput :: PRINTSTRING()+ 0xB5执行字节
CSC.EXE!ConsoleOutput :: PrintBanner()+ 0x50为
CSC.EXE!_main()+ 0x2d0eb字节

有关WideToConsole()不可用实​​际的代码,最接近的匹配是这个版本从SSCLI20分布:

  / * 
*就像调用WideCharToMultiByte,但转换到控制台的代码页。返回的长度,
*包括null终止符。
* /
INT ConsoleOutput :: WideCharToConsole(LPCWSTR wideStr,LPSTR lpBuffer,诠释nBufferMax)
{
如果(m_fUTF8Output){
如果(nBufferMax == 0) {
返回UTF8LengthOfUnicode(wideStr,(INT)wcslen(wideStr))+ 1; // +1 NUL终止
}
,否则{
INT cchConverted = NULL_TERMINATED_MODE;
返回UnicodeToUTF8(wideStr,&安培; cchConverted,lpBuffer,nBufferMax);
}

}
,否则{
返回调用WideCharToMultiByte(GetConsoleOutputCP(),0,wideStr,-1,lpBuffer,nBufferMax,0,0);
}
}

/ *
*转换Unicode字符串与VSAlloc
* /
HRESULT ConsoleOutput分配控制台ANSI字符串:: WideToConsole (LPCWSTR wideStr,CAllocBuffer&放​​大器;缓冲液)
{
INT CCH = WideCharToConsole(wideStr,NULL,0);
buffer.AllocCount(CCH);
如果(0 == WideCharToConsole(wideStr,buffer.GetData(),CCH)){
VSFAIL(你怎么字符串大小变化?);
//我们必须为NULL终止输出,因为调用WideCharToMultiByte没有
buffer.SetAt(0,'\0');
返回E_FAIL;
}
返回S_OK;
}



坠毁的地方周围的VSFAIL发生()断言,从机器编码判断。我可以看到返回E_FAIL声明。然而它从我张贴的版本改变时,if()语句被修改,它看起来像VSFAIL()由RETAILVERIFY()取代。 )爆发的东西时,他们做了这些变化,很可能在UnicodeToUTF8(现在名为UTF16ToUTF8()。再次强调,我的版本发布其实并没有崩溃,您可以通过运行C见自己:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe。只有CSC.EXE的V4版本有这个bug。



实际的错误是难以从机器代码挖掘出来,最好让有关Microsoft担心。您可以在connect.microsoft.com提交的bug。我没有看到类似的,还算可圈可点BTW的报告。对于这个错误的解决方法是使用CHCP更改代码页回来。


I am having am having or have run into a very strange thing.

I wonder if others have and why it's happening.

Having run a one line program with this line System.Console.WriteLine(System.Console.OutputEncoding.EncodingName); I see the Encoding is Western European (DOS)

Fine

Here is a list of some codepages1200 Unicode and 65001 utf-8 and Windows-1252 Western European (Windows) and 850 Western European DOS from https://msdn.microsoft.com/en-us/library/system.text.encoding(v=vs.110).aspx

Say I write a C sharp program to change the encoding to utf-8

class sdf
{
  static void Main(string[] args)
{
System.Console.WriteLine(System.Console.OutputEncoding.EncodingName);
  System.Console.OutputEncoding=System.Text.Encoding.GetEncoding(65001);
System.Console.WriteLine(System.Console.OutputEncoding.EncodingName);
}
}

It works, it prints

Western European (DOS)
Unicode (UTF-8)

Now when I run csc again, csc crashes.

I checked my RAM for 14 hours, 8 passes, with memtest. I ran chkdsk my hard drive, all fine. And this is definitely not those, this is a coding issue.I know that because if I open up a new cmd prompt, then run csc, it doesn't crash.

So running that c sharp program, changes the shell such that the next time just running csc crashes csc itself, in that big way.

If I compile the code below, then run it, then run csc, then run csc, or csc whatever.cs, I get csc crashing.

So close the cmd prompt, Open a new one.

This time, experiment with comment and uncommenting the second line of the program

I find that if the second line (the line that changes the codepage to 850 (DOS Western Europe), is there, then it it won't crash the next time I run csc.

Whereas if I comment out that second line, so the program exits having the codepage/encoding changed to UTF-8 then then next time csc runs, csc crashes.

// uncomment the last line, and then // this runs but makes csc crash next time.

class asdf
{
  static void Main()
  {

     System.Console.OutputEncoding = System.Text.Encoding.UTF8; //output and to utf8
     System.Console.OutputEncoding=System.Text.Encoding.GetEncoding(850); 
  }
}

I am not the only person that has run into something like this

though no explanation was found there https://social.msdn.microsoft.com/Forums/vstudio/en-US/0e5f477e-0c32-4e88-acf7-d53d43d5b566/c-command-line-compiler-cscexe-immediately-crashes-when-run-in-code-page-65001-utf8?forum=csharpgeneral

I can deal with it by making sure the last line sets the codepage to 850. Though as i'll explain that's an inadequate solution..

Also i'd like to know if this is some problem with CSC that others have too. Or any other solutions.

added

uuu1.cs

// uuu1.cs
class asdf
{
static void Main()
{

System.Console.InputEncoding  = System.Text.Encoding.UTF8;
System.Console.OutputEncoding = System.Text.Encoding.UTF8;

// not unicode.  UTF8 means redirection will then work

System.Console.WriteLine("ჵ");

// try redirecting too..

// and try  checking for csc crash or not
//System.Console.OutputEncoding=System.Text.Encoding.GetEncoding(850);
//System.Console.InputEncoding =System.Text.Encoding.GetEncoding(850);
//problem is that when that is commented, it breaks the redirection



}
}

Adding the line / uncomment the last lines so I have

System.Console.OutputEncoding=System.Text.Encoding.GetEncoding(850);

would stop the crash but is an inadequate solution, because for example.. If I want to redirect the output of a program to a file, then I need UTF8 all the way from beginning to end, otherwise it doesn't work

this works with the codepage 850 line uncommented

c:\blah>uuu1>r.r<ENTER>  
c:\blah>type r.r <ENTER>  
c:\blah>ჵ  

If I uncomment the last lines, thus changing the codepage to 850 then sure csc won't crash on the next run, but the redirection doesn't work and r.r doesn't contain that character.

Added 2

Han's answer makes me notice another way of triggering this error

C:\Users\harvey\somecs3>csc<ENTER>
Microsoft (R) Visual C# Compiler version 4.0.30319.18408
for Microsoft (R) .NET Framework 4.5
Copyright (C) Microsoft Corporation. All rights reserved.

warning CS2008: No source files specified
error CS1562: Outputs without source must have the /out option specified

C:\Users\harvey\somecs3>chcp  65001<ENTER>
Active code page: 65001

C:\Users\harvey\somecs3>csc<ENTER>  <-- CRASH

C:\Users\harvey\somecs3>
解决方案

Well, you found a bug in the way the C# compiler deals with having to output text to the console when it is switched to UTF-8. It has a self-diagnostic to ensure the conversion from an UTF-16 encoded string to the console output code page worked correctly, it slams the Big Red Button when it didn't. The stack trace looks like this:

csc.exe!OnCriticalInternalError()  + 0x4 bytes  
csc.exe!ConsoleOutput::WideToConsole()  + 0xdc51 bytes  
csc.exe!ConsoleOutput::print_internal()  + 0x2c bytes   
csc.exe!ConsoleOutput::print()  + 0x80 bytes    
csc.exe!ConsoleOutput::PrintString()  + 0xb5 bytes  
csc.exe!ConsoleOutput::PrintBanner()  + 0x50 bytes  
csc.exe!_main()  + 0x2d0eb bytes    

The actual code for WideToConsole() is not available, the closest match is this version from the SSCLI20 distribution:

/*
 * Like WideCharToMultiByte, but translates to the console code page. Returns length,
 * INCLUDING null terminator.
 */
int ConsoleOutput::WideCharToConsole(LPCWSTR wideStr, LPSTR lpBuffer, int nBufferMax)
{
    if (m_fUTF8Output) {
        if (nBufferMax == 0) {
            return UTF8LengthOfUnicode(wideStr, (int)wcslen(wideStr)) + 1; // +1 for nul terminator
        }
        else {
            int cchConverted = NULL_TERMINATED_MODE;
            return UnicodeToUTF8 (wideStr, &cchConverted, lpBuffer, nBufferMax);
        }

    }
    else {
        return WideCharToMultiByte(GetConsoleOutputCP(), 0, wideStr, -1, lpBuffer, nBufferMax, 0, 0);
    }
}

/*
 * Convert Unicode string to Console ANSI string allocated with VSAlloc
 */
HRESULT ConsoleOutput::WideToConsole(LPCWSTR wideStr, CAllocBuffer &buffer)
{
    int cch = WideCharToConsole(wideStr, NULL, 0);
    buffer.AllocCount(cch);
    if (0 == WideCharToConsole(wideStr, buffer.GetData(), cch)) {
        VSFAIL("How'd the string size change?");
        // We have to NULL terminate the output because WideCharToMultiByte didn't
        buffer.SetAt(0, '\0');
        return E_FAIL;
    }
    return S_OK;
}

The crash occurs somewhere around the VSFAIL() assert, judging from the machine code. I can see the return E_FAIL statement. It was however changed from the version I posted, the if() statement was modified and it looks like VSFAIL() was replaced by RETAILVERIFY(). Something broke when they made those changes, probably in UnicodeToUTF8() which is now named UTF16ToUTF8(). Re-emphasizing, the version I posted does not in fact crash, you can see for yourself by running C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe. Only the v4 version of csc.exe has this bug.

The actual bug is hard to dig out from the machine code, best to let Microsoft worry about that. You can file the bug at connect.microsoft.com. I don't see a report that resembles it, fairly remarkable btw. The workaround for this bug is to use CHCP to change the codepage back.

这篇关于为什么CSC.EXE崩溃当我最后一次离开输出编码为UTF8?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 10:35