【问题标题】:TexTransform cli and the copyright symbolTexTransform cli 和版权符号
【发布时间】:2026-02-16 06:55:01
【问题描述】:

在遵循here 的指导后,我实施了一个专为dynamical update assembly copyright 设计的预构建过程。

版权的模板是

<#@ template language="C#" #>
<#@ output extension=".cs" #>
using System;
using System.Reflection;

[assembly: AssemblyCopyright("Copyright © <#=DateTime.Now.Year#>")]

如果我将文件保存在 VS 中,生成的文件(和编译的程序集)正确地包含版权符号 (©)。当作为预构建调用 TextTransform.exe(在本例中为 v12.0)的一部分完成时,生成的文件包含“?”反而。指定 encoding="us-ascii" 时,我得到相同的结果当编码设置为任何 utf 变体时,它会显示为“�”。修改模板以使用 \u00A9 会在编译程序集时得到相同的结果。

我知道我可以合并code generation in the solution build process,但这增加了新员工(和新环境设置;我们在 VM 中进行大量开发)的负担,以确保安装适当的 SDK。它还需要使用模板对每个项目进行人工干预(我们小组在一年内完成了许多不同的项目,其中许多项目需要多年的持续维护)。该过程还强制重新生成每个构建(预构建事件生成到临时文件并在尝试覆盖之前比较差异)。最后,这条路径的结果似乎与预构建事件相同。

我还缺少哪些其他选项?

【问题讨论】:

    标签: visual-studio templates t4 pre-build-event


    【解决方案1】:

    我在版权符号方面遇到了同样的问题,并为我的 T4 模板找到了这个解决方案。

    [assembly: AssemblyCopyright("Copyright <#='\u00A9'#> <#=DateTime.Now.Year#>")]
    

    对不起,我不能早点帮到你。

    【讨论】:

      【解决方案2】:

      要具体回答我的问题:我缺少的至少一个其他选项涉及编写自定义实用程序来为我生成 cs 文件。只有当文件实际上不同或尚不存在时,此代码才会写出带有正确版权标记的文件。

      我已经将它实现为一个控制台应用程序,目标是使用 VS2015 编写的第 4 版框架。

      namespace GenerateAssemblyCopyright
      {
        class Program
        {
          const string _fileName = "AssemblyCopyright.cs";
          static void Main(string[] args)
          {
            if (args.Length == 0 || !Directory.Exists(args[0]))
              throw new InvalidOperationException("Must supply path for assembly copyright file");
      
            var acPath = Path.Combine(args[0], _fileName);
            var potentialOutput = $@"using System;
      using System.Reflection;
      
      [assembly: AssemblyCopyright(""Copyright © {DateTime.Now.Year}"")]";
            var exitingOutput = string.Empty;
      
            if (File.Exists(acPath))
            {
              using (var sr = new StreamReader(acPath, true))
              {
                exitingOutput = sr.ReadToEnd();
              }
            }
      
            if (!exitingOutput.Equals(potentialOutput))
            {
              using (var sw = new StreamWriter(acPath, false, Encoding.UTF8))
              {
                sw.Write(potentialOutput);
              }
            }
          }
        }
      }
      

      我将生成的 exe 复制到解决方案目录并在解决方案中的第一个项目上定义预构建事件。

      :: set the correct path to the the GenerateCopyright app
      set "generateExe=$(SolutionDir)GenerateAssemblyCopyright.exe"
      
      "%generateExe%" "$(SolutionDir)\"
      

      需要注意的一点:尽管$(SolutionDir) 已经包含一个尾部反斜杠 (),但在作为 exe args 的一部分传入时,还需要一个额外的反斜杠来防止将最后一个引号变成转义引号。

      【讨论】:

        最近更新 更多