调试 T4 文本模板

您可以在文本模板中的断点。 若要调试设计时文本模板,选择在文本模板文件的快捷菜单中 调试 T4 模板 在解决方案资源管理器中。 若要调试一个运行时文本模板,调试其所属的应用程序。

若要调试文本模板,应了解模板转换过程的步骤。 不同类型错误每个步骤中可能会发生。 步骤如下所示。

步骤

设计时模板:当出现此警告。

运行时模板:当出现此警告。

代码从文本模板生成。

在指令或不匹配的或 scrum 的 <#…#> 标记的错误。

当您保存模板或调用文本转换。

当您保存模板或调用文本转换。

生成的代码编译。

在模板代码的编译错误。

在前面的步骤之后。

与应用程序代码。

代码运行。

在模板代码的运行时错误。

在前面的步骤之后。

当应用程序运行并调用模板代码。

在大多数情况下,会在错误报告中提供模板代码中的行号。 如果错误报告引用临时文件名,则原因通常是文本模板代码中的括号不匹配。

您可以在文本模板中的断点和调试以常规方式。

常见错误以及解决

下表列出了最常见的错误及其解决方法。

错误消息

描述

解决方案

未能加载从其中继承转换类的基类“{0}”。

在模板指令中找不到 inherits 参数中指定的基类时发生。 该消息提供模板指令的行数。

确保存在指定的类,并确保该类存在的程序集在程序集目录中指定。

未能解析文件 {0} 的包含文本

找不到包含的模板时发生。 消息提供所请求的包含文件的名称。

确保文件路径相对于原始模板路径,或者确保文件路径位于用主机注册的位置,或者确保存在访问文件的完整路径。

初始化转换对象时出错。 转换将不会运行。

转换类的 'Initialize()' 失败或返回假时发生。

Initialize() 函数中的代码来自 <#@template#> 指令中指定的基转换类以及指令处理器。 导致初始化失败的错误可能列于错误列表上。 调查失败原因。 您可以按照以下过程查看为 Initialize() 实际生成的代码来调试模板。

指令处理器“{1}”的程序集“{0}”未被授予 FullTrust 权限集。 仅允许受信任的程序集提供指令处理器。 将不加载此指令处理器。

系统未授予包含指令处理器的程序集 FullTrust 权限时发生。 消息提供程序集的名称和指令处理器的名称。

确保只使用本地计算机上受信任的程序集。

路径 '{0}' 必须对于此计算机或受信任的区域的一部分是本地的。

指令或程序集指令引用不在本地计算机上或网络的受信任区域内的文件时发生。

应确保目录或程序集指令所在的目录属于受信托区域。 您可以通过 Internet Explorer 将网络目录添加到受信任区域。

多个语法错误,如“无效令牌 'catch'”或“A 命名空间不能直接包含成员”

模板代码中的右括号太多。 编译器将它与标准生成代码混淆。

检查代码分隔符内的右大括号和尖括号的号码。

循环或条件未编译或正确执行。 例如:

<#if (i>10)#>
   Number is: <#= i #>.

此代码始终输出 i 的值。 只有"号码是:"是有条件的。

在 C# 中,始终使用大括号括起控制语句中嵌入的文本块。

添加括号:

<#if (i>10) { #>
   Number is: <#= i #>.
<# } #>

当处理设计时模板或编译运行时(预处理)模板时,“表达式太复杂”。

尝试检查由运行时模板生成的代码时,Visual Studio 停止工作。

文本块太长。 T4 将文本块转换为字符串串联表达式,每一个模板行对应一个字符串文本。 很长的文本块可以超越编译器的大小限制。

将长的文本块分解为表达式块,如:

<#= "" #>

警告说明和修补程序

下表列出了最常见的警告以及解决办法(如果可用)。

警告消息

描述

解决方案

加载包含文件“{0}”时,返回了 null 或空字符串。

包含的文本模板文件为空时发生。 消息提供包含的文件的文件名。

移除 include 指令,或者确保该文件包含某些内容。

编译转换:

将此字符串追加到编译转换时从编译器发出的所有错误或警告。 此字符串意味着编译器引发错误或警告。

如果在查找 DLL 时有问题,若 DLL 是在 GAC 中,则可能需要提供完整的路径或完全限定的强名称。

参数 '{0}' 已存在于指令中。 将忽略重复的参数。

在指令中多次指定一个参数时发生。 消息提供参数名称以及指令的行号。

删除重复参数规范。

加载包含文件 '{0}' 时出错。 将忽略该包含指令。

在 include 指令中找不到指定的文件时发生。 消息提供文件名称以及指令的行号。

确保包含文件存在于与原始文本模板文件相同的目录中或存在于用主机注册的包括目录之一的文件。

为 Transformation 类指定的基类无效。 基本类必须派生自 Microsoft.VisualStudio.TextTemplating.TextTransformation。

模板指令中的 inherits 参数指定未从 TextTransformation 继承的类时发生。 该消息提供模板指令的行数。

指定一个从 TextTransformation 派生的类。

在“template”指令中指定了无效的区域性。 区域性必须采用“xx-XX”格式。 将使用固定的区域性。

错误地指定模板指令中的区域性参数时发生。 该消息提供模板指令的行数。

将区域性参数更改为格式为“xx-XX”的有效区域性。

在模板指令中指定了无效的调试值 '{0}'。 该调试值必须为“true”或“false”。 将使用默认值“false”。

错误地指定模板指令中的 debug 参数时发生。 该消息提供模板指令的行数。

将调试参数设置为“true”或“false”。

在模板指令中指定了无效的 HostSpecific 值 '{0}'。 HostSpecific 值必须是“true”或“false”。 将使用默认值“false”。

错误地指定 template 模板指令中的参数时发生。 该消息提供模板指令的行数。

将特定与宿主的参数设置为“true”或“false”。

在“模板”指令中指定了无效的语言 '{0}'。 该语言必须为“C#”或“VB”。 将使用默认值“C#”。

在 template 中指定了不支持的语言时发生。 只允许“C#”或者“VB”(不区分大小写)。 该消息提供模板指令的行数。

在模板指令中将 language 参数设置为“C#”或“VB”。

在模板中找到多个 output 指令。 将忽略除第一个指令之外的所有指令。

在一个模板文件中指定多个 output 指令时发生。 该消息提供重复输出指令的行数。

删除重复的 output 指令。

在模板中找到多个 template 指令。 将忽略除第一个指令之外的所有指令。 应在一个 template 指令内指定该 template 指令的多个参数。

在一个文本模板文件(包括包含的文件)内指定多个 template 指令时发生。 该消息提供重复模板指令的行数。

将不同 template 指令聚合到一个 template 指令。

没有为名为“{0}”的指令指定处理器。 将忽略该指令。

指定 custom 指令但未提供 processor 特性时发生。 消息提供指令名称和行数。

提供 processor 特性,其具有指令 directive 处理器的名称。

名为“{0}”的处理器未能找到名为“{1}”指令。 将忽略该指令。

系统在 custom 指令中找不到指定的 directive 处理器时发生。 消息提供指令名称、处理器名称以及指令的行号。

将指令中的 processor 特性设置为指令处理器的名称。

未找到指令“{1}”所需的参数“{0}”。 将忽略该指令。

系统未提供所需的指令参数时发生。 消息提供缺失参数的名称、指令名称和行号。

提供缺少的参数。

名为“{0}”的处理器不支持名为“{1}”的指令。 将忽略该指令。

指令处理器不支持一个指令时发生。 消息提供有问题的指令和指令处理器的名称和行数。

更正指令的名称。

文件“{0}”包含指令将导致无限循环。

如果指定了循环 include 指令(例如,文件 A 包含文件 B,文件 B 又包括文件 A),则会显示。

不指定循环 include 指令。

运行转换:

将此字符串追加到运行转换时生成的所有错误或警告。

不适用。

在块内发现意外的开始或结束标记。 请确保未错误地键入开始或结束标记并且在模板中不包含任何嵌套的块。

在您具有意外 <# 或 #> 时显示。 也就是说,如果您具有 <#(在另一个尚未关闭的打开标记之后),或者具有一个 #>(在它之前没有未关闭的打开标记)。 该消息提供不匹配标记的行数。

移除不匹配的开始或结束标记,或者使用转义字符。

以错误的格式指定了某个指令。 将忽略该指令。 按以下格式指定该指令:<#@ name [parametername="parametervalue"]* #>

如果没有以正确格式指定指令,则由分析器显示。 该消息提供不正确指令的行数。

确保所有的指定的格式为 <#@ name [parametername="parametervalue"]* #>。 有关更多信息,请参见T4 文本模板指令

未能加载注册指令处理器“{1}”的程序集“{0}”

{2}

未能由主机加载指令处理器时发生。 该消息标识为指令处理器提供的程序集,以及指令处理器的名称。

确保正确注册指令处理器和确保存在程序集。

未能在程序集“{1}”中找到注册指令处理器“{2}”的类型“{0}”

{3}

未能从程序集加载指令处理器类型时发生。 消息提供类型、程序集和指令处理器的名称。

该 vshost 查找注册表中的指令处理器信息(名称、程序集和类型)。 确保正确注册指令处理器和确保程序集中存在类型。

加载程序集 '{0}' 时出现问题

加载程序集有问题时发生。 消息提供程序集的名称。

您可以指定要在 <@#assembly#> 指令中加载的程序集以及指令处理器加载的程序集。 遵循此单词符串的错误消息应提供更多有关程序集加载失败的数据。

创建并初始化一个名为 '{1}' 的指令处理器时出现问题。 处理器的类型为 {0}。 将忽略该指令。

系统未能创建或初始化指令处理器时发生。 消息提供指令和处理器类型的名称和行数。

确保使用正确的指令处理器,并确保指令处理器拥有公共默认构造函数。 否则使用调试选项找出的指令处理器 Initialize() 方法失败的原因。 有关更多信息,请参见调试 T4 文本模板

处理名为“{0}”的指令时引发了异常。

指令处理器在处理一个指令时引发异常时发生。

确保指令处理器参数的正确性。

在尝试解析程序集引用“{0}”时,主机引发了异常。

主机尝试解析程序集引用时抛出异常时发生。 信息提供程序集引用字符串。

程序集引用来自 <@#assembly#> 指令和指令处理器。 确保 assembly 参数中提供的“名称”参数的正确性。

尝试指定不受支持的指令 {2} 的 {1} 值 '{0}'

提供不支持的请求或提供参数(所有生成的指令处理器都由此派生)时由RequiresProvidesDirectiveProcessor 触发。

确保 requires 和 provides 参数中提供的名称='值' 对的正确性。