65.9K
CodeProject 正在变化。 阅读更多。
Home

解决 TFS 中的 .resx 合并问题

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2013 年 9 月 6 日

CPOL
viewsIcon

28689

downloadIcon

306

这是“解决 .resx 合并问题”的另一种方案

 简介

本文扩展了 原始文章,介绍了如何在 TFS 实现中解决 .resx 文件的合并问题。但可以轻松调整以适用于 ant diff 合并应用程序。

使用代码

在 Visual Studio 中执行以下操作:工具 -> 选项 -> 源代码管理 -> Visual Studio Team Foundation Server -> 配置用户工具

点击“添加”并填写
扩展名:.resx
操作:比较
命令:C:\SortRESX.exe
参数:compare %1 %2 %6 %7 %5

点击“确定”,然后再次点击“添加”并填写
扩展名:.resx
操作:合并
命令:C:\SortRESX.exe
参数:merge %1 %2 %3 %4 %6 %7 %8 

代码

该程序在启动 TFS 合并实用程序之前,使用原始文章中的排序功能。

class Program
{
    private const string DiffMergeLocation = 
      @"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\diffmerge.exe";

    static void Main(string[] args)
    {
        //Are we mergeing or comparing
        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
        {
            //Sort input files
            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] + "\"" : "";

            //Launch diffmerge and wait for exit
            var start = new ProcessStartInfo
            {
                Arguments = string.Format("\"{0}\" \"{1}\" \"{2}\" 
                  \"{3}\" /ignorespace", theirs, yours, theirLabel, yoursLabel),
                FileName = DiffMergeLocation,
                CreateNoWindow = true,
                WindowStyle = ProcessWindowStyle.Hidden
            };

            // Run the external process & wait for it to finish
            using (var proc = Process.Start(start))
            {
                proc.WaitForExit();
            }
        }
        finally
        {
            //Clean up temp files
            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
        {
            //Sort input files
            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);

            //Launch diffmerge and wait for exit
            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
            };

            // Run the external process & wait for it to finish
            using (var proc = Process.Start(start))
            {
                proc.WaitForExit();
            }
        }
        finally
        {
            //Clean up temp files
            File.Delete(theirs);
            File.Delete(yours);
            File.Delete(baseFile);
        }
    }

    /// <summary>
    /// Use Linq to sort the elements.  The comment, schema, resheader, assembly, metadata, data appear in that order, 
    /// with resheader, assembly, metadata and data elements sorted by name attribute.
    /// </summary>
    /// <param name="resx"></param>
    /// <returns></returns>
    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"))
            )
        );
    }
}
© . All rights reserved.