裝好VS2015後,陸續將VS2013維護的專案改用VS2015開啟,原以為可完全無痛移轉,踩到小刺一根。

某個用VS2013開發多時的專案,移到VS2015出現編譯錯誤!以下面的程式為例:

Console.WriteLine那行發生Unrecoginzed escape sequence錯誤。

看到Unrecongized escape又看了看問題字串,程式老骨頭心中警鈴聲大作:

我被「許功蓋」偷襲了?

使用Notepad++開啟C#原始檔,果不其然,檔案編碼被設成BIG5(ANSI)。

依開發規範,程式檔都該存成UTF8編碼,避免中文難字或非中文的Unicode字元變成亂碼。出問題的.cs檔案有點歷史,漏了修改,但從VS2005時代至今多年,相安無事。由此推論,VS2013面對BIG5編碼原始碼檔案有較高的包容性,VS2015的處理邏輯改變(可能是編譯器改用Roslyn的緣故),遇到許功蓋等包含"\"字元的BIG5中文字,發生解析錯誤。而依文字出現位置的不同,產生的錯誤也可能不同,例如:若將以上程式改成Console.WriteLine("測試成功"),錯誤訊息則會變成:

1>e:\L1\Lab1\Program.cs(13,31,13,31): error CS1010: Newline in constant
1>e:\L1\Lab1\Program.cs(13,43,13,43): error CS1003: Syntax error, ',' expected
1>e:\L1\Lab1\Program.cs(14,27,14,28): error CS1026: ) expected

【結論】VS2015處理ANSI編碼程式檔邏輯與VS2013不同,若專案搬移至VS2015後出現Unrecoginzed escape sequence或字串結尾識別失敗等相關錯誤,請優先檢查是否程式檔被存成ANSI(BIG5)編碼,轉為UTF8即可排除。

【2015-08-07 更新】補充:潛盾機-解決VS2015程式檔BIG5相容問題

【2015-08-12 更新】補充:VS2015程式檔BIG5相容問題快速解法-修改csproj/vbproj


Comments

# by 浪海中的一條小腸

未來微軟會修正這樣的問題嗎?? 公司有很多的舊專案似乎都有用到 中文 像是 Enum 有人是用中文寫

# by Jeffrey

to 浪海中的一條小腸, 在程式碼中寫中文甚至Enum用中文寫並不是問題,關鍵在檔案存檔時編碼不要選BIG5(ANSI),改成UTF8就一切OK。 BIG5編碼已過時,未來如遇到中文難字、其他國家文字及特殊符號時還有其他怪要打,我比較建議趁此機會對舊專案的編碼進行清查,如有使用BIG5的程式碼一律改成UTF8,一勞永逸。

# by kevinst

可是有將近1萬個cs檔在2015都編譯不過,但在vs2013卻是OK的,光是都要另存成utf8 就讓人手軟,VS2015 就先不用了

# by Jeffrey

to kevinst, 如果有大量程式碼都被存成BIG5,可以寫支.NET小程式批次轉完,幾分鐘內應可搞定。請參考: var code = System.IO.File.ReadAllText(srcPath, System.Text.Encoding.GetEncoding(950)); System.IO.File.WriteAllText(dstPath, code, System.Text.Encoding.UTF8);

# by Rex

Jeffrey你好,前述你有提到Enum用中文不會是問題(若採用UTF8的話)。 除卻專案人員為多國籍組成狀態下,究竟Enum用中文會不會被關切呢? 現在聽過的說法都是不建議

# by Jeffrey

to Rex, 我個人非常反對在檔名、類別名稱、變數、列舉名稱使用中文,理由是寫程式引用時輸入中文會減損效率,另外雖然中文名稱在規格上合法,但整個開發及執行環境中若是有某個環節考慮不周,就會遇到麻煩(例如:HTML/ASP用中文檔名在轉成URL時就可能踩到瀏覽器的地雷,但近年來已較少發生)。 除非有非常堅強的理由(例如:不取中文不驗收),我不建議在程式碼相關的命名使用中文,但使用中文畢竟算不上違反.NET規範,各開發團隊可以依自己的情境評估決定是否禁用。

# by StevenWang

如果有大批檔案要轉換,可以考慮使用免費的 Convertz 來整個目錄轉換?

# by Jeffrey

to StevenWang, 我後來寫了小工具批次換檔,網友也補充了Convertz跟UTFCast兩套軟體,有個更簡單的解法是直接改csproj檔,細節可參考文末的文章連結。感謝你的回饋。

Post a comment


56 - 40 =