CSI: Visual Studio—索引到指定的代码页无法转换Unicode字符


[原文发表地址] CSI: Visual Studio – Unable to translate Unicode character at index X to specified code page

[原文发表时间] 2013-06-08

A crazy internal error from Visual Studio

一位用户发邮件告诉我一件怪异的事。当一件不起眼的事情发生了,我倾向于将它变成一些有趣的事情。

那个用户说到:

…鬼使神差地,我的大部分项目拒绝被构建,”由于一些内部故障…有关Unicode之类的事情…构建意外停止”

关于这个问题在网络上有几个消息—甚至有一个说法提到热修复程序。对VS团队/微软来说应对这个问题用什么样的方式最好呢?是否有任何活跃用户对这样的故障有兴趣呢?

我那蜘蛛侠一般的情绪被调动起来了。首先,当提到”内部故障”,这就意味着一些基本的期望没有得到满足。也许是垃圾?他说”我的大部分项目”这暗示着它不是某个特定的项目,还有一种可能,这是一个”突然停止工作”之类的事情,据推测,这个项目之前是可以被构建的。

我回复:

你检查过所有的源文件来确保没有用Unicode为空或其它什么来填充么?

他说没有,但是发送了一个调用堆栈给我(当它第一次发送时始终是好的,但是):

Error    1    The build stopped unexpectedly because of an internal failure.
System.Text.EncoderFallbackException: Unable to translate Unicode character \uD97C at index 1321 to specified code page.
   at System.Text.EncoderExceptionFallbackBuffer.Fallback(Char charUnknown, Int32 index)
   at System.Text.EncoderFallbackBuffer.InternalFallback(Char ch, Char*& chars)
   at System.Text.UTF8Encoding.GetByteCount(Char* chars, Int32 count, EncoderNLS baseEncoder)
   at System.Text.UTF8Encoding.GetByteCount(String chars)
   at System.IO.BinaryWriter.Write(String value)
   at Microsoft.Build.BackEnd.NodePacketTranslator.NodePacketWriteTranslator.TranslateDictionary(Dictionary`2& dictionary, IEqualityComparer`1 comparer)
   at Microsoft.Build.Execution.BuildParameters.Microsoft.Build.BackEnd.INodePacketTranslatable.Translate(INodePacketTranslator translator)
   at Microsoft.Build.BackEnd.NodePacketTranslator.NodePacketWriteTranslator.Translate[T](T& value, NodePacketValueFactory`1 factory)
   at Microsoft.Build.BackEnd.NodeConfiguration.Translate(INodePacketTranslator translator)
   at Microsoft.Build.BackEnd.NodeProviderOutOfProcBase.NodeContext.SendData(INodePacket packet)
   ...

好了,看起来它确实不喜欢字符。但是什么字符呢?我们假定有这么一个源文件,但重要的是要记住有类似路径名、环境变量、或者类似switch的命令输入到一个编译器中。

在内部故障之前,提示说索引1321看起来似乎是一个遥不可及的字符串。我问了几个人,其中Sara Joiner说:

我们对字串或其他部分不做任何修改—只是将一个dictionary 传送出去,其中包括第一次写的大小,然后是每一个键和值。因此,如果数据是坏的,我不认为是MSBuild做了什么引起的。也就是说,它看起来是唯一一个可以放进BuildParameters的地方,我们称之为TranslateDictionary,用来跨网络线路传输的环境[变量]状态。

所以这是分裂的环境变量名称-值配对!David Kean说:“询问下他的路径看起来是什么样的”。我问了,同时得到了将近2000个字节的路径!这是一个巨大的路径,它看起来像是甚至可能被复制并追加本身好几次。

这里只是一个有点问题的路径,看见什么了吗?

\;C:\PROGRA~1\DISKEE~1\DISKEE~1\;C:\Program Files (x86)\Windows Kits\8.0\Windows
Performance Toolkit\;C:\Program Files\Microsoft SQL
Server\110\Tools\Binn\;C:\Program Files\Microsoft\Web Platform
Installer\;C:\Program Files\TortoiseSVN\binVN\???p??;C:\Program
Files\TortoiseSVN\bin;C:\PHP\;C:\progra~1\NVIDIA
Corporation\PhysX\Common;C:\progra~2\Common Files\Microsoft Shared\Windows
Live;C:\progra~1\Common Files\Microsoft Shared\Windows
Live;C:\q\w32;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;
C:\Windows\System32\WindowsPowerShell\v1.0\;C:\progra~2\WIDCOMM\Bluetooth
Software\;C:\progra~2\WIDCOMM\Bluetooth 

看到这些了吗???这些标记?对我来说这不是问号标记。我打开在Visual Studio中作为二进制文件“SET > env.txt”保存的结果,它看起来像是3Fs,这些是问号的标记。

I think the text file was converted to ANSI

 

这不禁让我想到含有Unicode的路径如何通过管道转换成ANSI。措辞不同,这个文本文件并不现实。

然而,在Windows用户界面的其他地方看起来像是它的路径变量不同。

C:\Program Files\TortoiseSVN\binVN\�侱ᤣp䥠؉;

有时候路径看起来是这样的,你可能会认为它是中文。不,这种现象被解释为Unicode。有趣的是,错误提示这是&#0xD97C; 中的0xD97C这样的顽皮的字符,这意味着一些处理过的东西被剥离出来变成了Unicode,相当于“呃…”,无论如何,这是错的,它需要被删除。

我问他是否清理他的路径就能构建成功,用户只是通过电子邮件回复…这也是最好的一种回复:

========== Build: 12 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

耶!我希望这有助于下一个遇到这个问题并去Google搜寻答案的人们,他们也独自思考过。

感谢David Kean,Sara Joiner和Srinivas Nadimpalli与我一起查看调用堆栈信息及推想出解决方案。

亲爱的读者,你有什么见解呢?


Comments (0)

Skip to main content