解决TFS中.resx文件合并问题的方法

在团队开发环境中,资源文件(.resx)的合并是一个常见的问题。Visual StudioTeam Foundation Server (TFS) 提供了版本控制功能,但并不直接支持.resx文件的合并。本文将介绍如何通过配置Visual Studio和编写辅助程序来解决这一问题。

配置Visual Studio

首先,需要在Visual Studio中配置源代码管理工具,以便能够比较和合并.resx文件。以下是详细步骤:

  1. 打开Visual Studio。
  2. 点击“工具”菜单,选择“选项”。
  3. 在“源代码管理”下,选择“Visual Studio Team Foundation Server”。
  4. 点击“配置”按钮。
  5. 在“用户工具”部分,点击“添加”按钮。
  6. 填写扩展名为“.resx”的比较和合并操作。
  7. 对于“比较”操作,命令行填写为“C:\SortRESX.exe compare %1 %2 %6 %7 %5”。
  8. 对于“合并”操作,命令行填写为“C:\SortRESX.exe merge %1 %2 %3 %4 %6 %7 %8”。
  9. 点击“确定”保存配置。

这样,就可以在Visual Studio中使用“比较”和“合并”功能来处理.resx文件了。

编写辅助程序

为了实现.resx文件的比较和合并,需要编写一个辅助程序。以下是一个使用C#编写的示例程序:

class Program { private const string DiffMergeLocation = @"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\diffmerge.exe"; static void Main(string[] args) { if (String.Equals(args[0], "merge", StringComparison.CurrentCultureIgnoreCase)) { HandleMerge(args); } else if (String.Equals(args[0], "compare", StringComparison.CurrentCultureIgnoreCase)) { HandleCompare(args); } else { throw new NotSupportedException("Unknown mode, use either merge or compare"); } } private static void HandleCompare(string[] args) { var theirsSource = args[1]; var theirs = Path.GetTempFileName(); var yoursSource = args[2]; var yours = Path.GetTempFileName(); try { var doc = XDocument.Load(theirsSource); var sortedDoc = SortDataByName(doc); sortedDoc.Save(theirs); doc = XDocument.Load(yoursSource); sortedDoc = SortDataByName(doc); sortedDoc.Save(yours); var theirLabel = args[3]; var yoursLabel = args[4]; var options = args.Length >= 6 ? "\"" + args[5] + "\"" : ""; var start = new ProcessStartInfo { Arguments = string.Format("\"{0}\" \"{1}\" \"{2}\" \"{3}\" /ignorespace", theirs, yours, theirLabel, yoursLabel), FileName = DiffMergeLocation, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden }; using (var proc = Process.Start(start)) { proc.WaitForExit(); } } finally { File.Delete(theirs); File.Delete(yours); } } private static void HandleMerge(string[] args) { var theirsSource = args[1]; var theirs = Path.GetTempFileName(); var yoursSource = args[2]; var yours = Path.GetTempFileName(); var baseFileSource = args[3]; var baseFile = Path.GetTempFileName(); var merged = args[4]; var theirLabel = args[5]; var yoursLabel = args[6]; try { var doc = XDocument.Load(theirsSource); var sortedDoc = SortDataByName(doc); sortedDoc.Save(theirs); doc = XDocument.Load(yoursSource); sortedDoc = SortDataByName(doc); sortedDoc.Save(yours); doc = XDocument.Load(baseFileSource); sortedDoc = SortDataByName(doc); sortedDoc.Save(baseFile); var start = new ProcessStartInfo { Arguments = string.Format("/merge \"{0}\" \"{1}\" \"{2}\" \"{3}\" \"{4}\" \"{5}\"", theirs, yours, baseFile, merged, theirLabel, yoursLabel), FileName = DiffMergeLocation, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden }; using (var proc = Process.Start(start)) { proc.WaitForExit(); } } finally { File.Delete(theirs); File.Delete(yours); File.Delete(baseFile); } } private static XDocument SortDataByName(XDocument resx) { return new XDocument( new XElement(resx.Root.Name, resx.Root.Nodes().Where(comment => comment.NodeType == XmlNodeType.Comment), resx.Root.Elements().Where(schema => schema.Name.LocalName == "schema"), resx.Root.Elements("resheader").OrderBy(resheader => (string)resheader.Attribute("name")), resx.Root.Elements("assembly").OrderBy(assembly => (string)assembly.Attribute("name")), resx.Root.Elements("metadata").OrderBy(metadata => (string)metadata.Attribute("name")), resx.Root.Elements("data").OrderBy(data => (string)data.Attribute("name")) ) ); } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485