意外字符 ''

Unexpected character ''

从 VS2013 迁移到 VS2017 后,我 运行 遇到了意外的字符问题。

在 msbuild 12.0 和 VS2013 中一切正常,但是当移动到 15.0 时,我收到数百个:

CS1519 Invalid token '?' in class, struct, or interface member declaration

在 msbuild 命令行中。

在 VS2017 中构建 returns:

CS1056 Unexpected character ''

var businessRuleData = principal.GetBusinessRule(​
BusinessRuleEnum.CONTENT_REPOSITORY);

Ch66 发生错误,位于该区域之间 (B。隐藏的字符在写字板中变为 ?。但是,如前所述,相同的代码在 msbuild 12.0 中构建良好。删除所有代码并重新下载 TFS 表格未能解决问题

解决方案代码

注意:在代码中搜索 change_me 并确保更改为您想要的项目。

using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

namespace FixZeroWidthSpace
{
    class Program
    {
        static void Main(string[] args)
        {
            // change to your directory
            var files = Directory.GetFiles(@"D:\change_me", "*.cs", SearchOption.AllDirectories);
            var counter = 0;
            var counterEdited = 0;
            var totalFiles = files.Length;
            var failed = new List<string>();
            var found = new List<string>();
            TfsTeamProjectCollection tpc = null;
            Workspace ws = null;

            foreach (var file in files)
            {
                if(counter % 10 == 0)
                {
                    Console.WriteLine("Searched {0} or {1} files, {2} have been edited.", counter, totalFiles, counterEdited);
                }
                // change to any folders you want to ignore or remove if none
                if (!file.Contains("change_me_ignore_folder_name"))
                {
                    string text = File.ReadAllText(file);
                    var regex = new Regex("[\u200B-\u200D\uFEFF]");
                    var newText = regex.Replace(text, "");

                    if (text != newText)
                    {
                        try
                        {
                            if (ws == null || tpc == null)
                            {
                                // change to your TFS server
                                tpc = new TfsTeamProjectCollection(new Uri(@"http://change_me_your_tfs_url/tfs/DefaultCollection"));
                                ws = FindWorkspaceByPath(tpc, file);
                            }

                            FileAttributes attributes = File.GetAttributes(file);

                            if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
                            {
                                attributes = RemoveAttribute(attributes, FileAttributes.Hidden);
                                File.SetAttributes(file, attributes);
                            }

                            ws.PendEdit(file);

                            if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                            {
                                // Make the file RW
                                attributes = RemoveAttribute(attributes, FileAttributes.ReadOnly);
                                File.SetAttributes(file, attributes);
                            }

                            File.WriteAllText(file, newText);
                            found.Add(file);
                            counterEdited++;
                        }
                        catch(Exception ex)
                        {
                            failed.Add(file);
                        }
                    }
                }
                counter++;
            }

            tpc.Dispose();
            File.WriteAllLines(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + "\found.txt", found);
            File.WriteAllLines(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + "\failed.txt", failed);

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }

        private static FileAttributes RemoveAttribute(FileAttributes attributes, FileAttributes attributesToRemove)
        {
            return attributes & ~attributesToRemove;
        }

        private static Workspace FindWorkspaceByPath(TfsTeamProjectCollection tfs, string workspacePath)
        {
            VersionControlServer versionControl = tfs.GetService<VersionControlServer>();
            WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(workspacePath);

            if (workspaceInfo != null)
            {
                return versionControl.GetWorkspace(workspaceInfo);
            }

            // No Workspace found using method 1, try to query all workspaces the user has on this machine.
            Workspace[] workspaces = versionControl.QueryWorkspaces(null, Environment.UserName, Environment.MachineName);
            foreach (Workspace w in workspaces)
            {
                foreach (WorkingFolder f in w.Folders)
                {
                    if (f.LocalItem.Equals(workspacePath))
                    {
                        return w;
                    }
                }
            }
            if (workspaces.Length > 0)
            {
                return workspaces[0];
            }

            throw new Exception(String.Format("TFS Workspace cannot be determined for {0}.", workspacePath));
        }
    }
}

解决方案

删除所有无效字符,因为 MSBuild 15.0 和 VS2017 对这些 un​​icode 字符更加严格。

可以使用以下代码来完成删除文件夹中所有有问题的代码。我使用它是因为所需的更改太大而无法手动完成。


C#代码

变量

[插入要扫描的文件夹]:示例 C:\TFS\Code\Branch\Folder
[插入要忽略的文件夹]:示例 3rdPartyCode

代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

namespace FixZeroWidthSpace
{
    class Program
    {
        static void Main(string[] args)
        {
            var files = Directory.GetFiles(@"D:\TFS0-2192\MCET_212", "*.cs", SearchOption.AllDirectories);
            var counter = 0;
            var counterEdited = 0;
            var totalFiles = files.Length;
            var failed = new List<string>();
            var found = new List<string>();

            foreach (var file in files)
            {
                if(counter % 10 == 0)
                {
                    Console.WriteLine("Searched {0} or {1} files, {2} have been edited.", counter, totalFiles, counterEdited);
                }
                if (!file.Contains("[Insert Folder To Ignore]"))
                {
                    string text = File.ReadAllText(file);
                    var regex = new Regex("[\u200B-\u200D\uFEFF]");
                    var newText = regex.Replace(text, "");

                    if (text != newText)
                    {
                        try
                        {
                            FileAttributes attributes = File.GetAttributes(file);

                            if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
                            {
                                attributes = RemoveAttribute(attributes, FileAttributes.Hidden);
                                File.SetAttributes(file, attributes);
                            }

                            if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                            {
                                // Make the file RW
                                attributes = RemoveAttribute(attributes, FileAttributes.ReadOnly);
                                File.SetAttributes(file, attributes);
                            }

                            File.WriteAllText(file, newText);
                            found.Add(file);
                            counterEdited++;
                        }
                        catch(Exception ex)
                        {
                            failed.Add(file);
                        }
                    }
                }
                counter++;
            }

            File.WriteAllLines(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + "\found.txt", found);
            File.WriteAllLines(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + "\failed.txt", failed);

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }

        private static FileAttributes RemoveAttribute(FileAttributes attributes, FileAttributes attributesToRemove)
        {
            return attributes & ~attributesToRemove;
        }
    }
}

带 TFS 校验的 C# 代码

变量

[插入要扫描的文件夹]:示例 C:\TFS\Code\Branch\Folder
[插入要忽略的文件夹]:示例 3rdPartyCode
[将 URI 插入 TFS 服务器集合]:示例 http://tfs.company.com:8080/tfs/DefaultCollection

代码

using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

namespace FixZeroWidthSpace
{
    class Program
    {
        static void Main(string[] args)
        {
            var files = Directory.GetFiles(@"[Insert Folder to Scan]", "*.cs", SearchOption.AllDirectories);
            var counter = 0;
            var counterEdited = 0;
            var totalFiles = files.Length;
            var failed = new List<string>();
            var found = new List<string>();
            TfsTeamProjectCollection tpc = null;
            Workspace ws = null;



            foreach (var file in files)
            {
                if(counter % 10 == 0)
                {
                    Console.WriteLine("Searched {0} or {1} files, {2} have been edited.", counter, totalFiles, counterEdited);
                }
                if (!file.Contains("3rdparty"))
                {
                    string text = File.ReadAllText(file);
                    var regex = new Regex("[\u200B-\u200D\uFEFF]");
                    var newText = regex.Replace(text, "");

                    if (text != newText)
                    {
                        try
                        {
                            if (ws == null || tpc == null)
                            {
                                tpc = new TfsTeamProjectCollection(new Uri(@"[Insert URI to TFS Server Collection]"));
                                ws = FindWorkspaceByPath(tpc, file);
                            }

                            FileAttributes attributes = File.GetAttributes(file);

                            if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
                            {
                                attributes = RemoveAttribute(attributes, FileAttributes.Hidden);
                                File.SetAttributes(file, attributes);
                            }

                            ws.PendEdit(file);

                            if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                            {
                                // Make the file RW
                                attributes = RemoveAttribute(attributes, FileAttributes.ReadOnly);
                                File.SetAttributes(file, attributes);
                            }

                            File.WriteAllText(file, newText);
                            found.Add(file);
                            counterEdited++;
                        }
                        catch(Exception ex)
                        {
                            failed.Add(file);
                        }
                    }
                }
                counter++;
            }

            tpc.Dispose();
            File.WriteAllLines(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + "\found.txt", found);
            File.WriteAllLines(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + "\failed.txt", failed);

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }

        private static FileAttributes RemoveAttribute(FileAttributes attributes, FileAttributes attributesToRemove)
        {
            return attributes & ~attributesToRemove;
        }

        private static Workspace FindWorkspaceByPath(TfsTeamProjectCollection tfs, string workspacePath)
        {
            VersionControlServer versionControl = tfs.GetService<VersionControlServer>();

            WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(workspacePath);

            if (workspaceInfo != null)
            {
                return versionControl.GetWorkspace(workspaceInfo);
            }

            // No Workspace found using method 1, try to query all workspaces the user has on this machine.
            Workspace[] workspaces = versionControl.QueryWorkspaces(null, Environment.UserName, Environment.MachineName);
            foreach (Workspace w in workspaces)
            {
                foreach (WorkingFolder f in w.Folders)
                {
                    if (f.LocalItem.Equals(workspacePath))
                    {
                        return w;
                    }
                }
            }

            throw new Exception(String.Format("TFS Workspace cannot be determined for {0}.", workspacePath));
        }
    }
}

我最近在我的一个解决方案中发现了这种情况。我的代码中没有它。

如果我清理解决方案(右键单击解决方案 -> 清理解决方案),问题就会消失。