gpt4 book ai didi

.net - 通过 TextTransform.exe 运行模板时使用 $(SolutionDir)

转载 作者:行者123 更新时间:2023-12-04 12:42:03 24 4
gpt4 key购买 nike

我试图让我们的 T4 模板在构建时运行,而不添加对 Visual Studio 建模 SDK 的依赖项。我已经成功使用了 here 显示的批处理文件的变体,但我现在遇到的问题是我的 .tt 文件使用了 $(SolutionDir)变量来引用其他项目(因此现在没有编译)。

处理这个问题的最佳方法是什么?其他人做了什么? (硬编码绝对路径不是一个选项)

编辑:
我看到有 -a可以传递给 TextTransform.exe 的参数,是否可以使用它来定义 $(SolutionDir) ?

最佳答案

查看 TextTransformation.exe 的源代码(使用 ILSpy)我认为如果不修改模板这是不可能的(但我确实有一个解决方案)。

最终我们在这里关心的是模板解析过程中的步骤,其中 Microsoft.VisualStudio.TextTemplating.Engine.ResolveAssemblyReferences() 叫做。这代表 ITextTemplatingEngineHost.ResolveAssemblyReference() (虽然它确实首先扩展了环境变量)

当模板从命令行运行时,所使用的实现是由 提供的。命令行主机 , 它的实现只是查找引用路径和 GAC 中提供的文件。鉴于此时文件名仍然包含 $(SolutionPath) 位,它永远不会成功。

您可以实现自己的 TextTransform.exe 版本,但您必须从头开始(或使用反射),因为 CommandLineHost 是内部的 :-( 或者您可能会利用 Mono 端口 https://stackoverflow.com/a/1395377/26167

我不能说我对此感到高兴,因为我发现自己在同一条船上......

编辑:但是...由于最终您需要做的就是更改模板,因此我编写了一个 PowerShell 脚本以将模板复制到临时目录,在此过程中手动扩展 $(SolutionDir) 宏,然后从那里执行它们。这似乎工作得很好。

将其放入有问题的项目中(您可能想要更改文件扩展名),您应该很高兴:

<#
.Synopsis
Executes all the T4 templates within designated areas of the containing project

.Description
Unfortunately the Visual Studio 2010 'Transform All Templates' function doesn't appear
to work in SSDT projects, so have to resort to hackery like this to bulk-execute templates
#>
param(

)

$ErrorActionPreference = 'stop';
$scriptDir = Split-Path $MyInvocation.MyCommand.Path

$commonProgramFiles32 = $env:CommmonProgramFiles
if (Test-Path environment::"CommonProgramFiles(x86)") { $commonProgramFiles32 = (gi "Env:CommonProgramFiles(x86)").Value };

$t4 = Resolve-Path "$commonProgramFiles32\Microsoft Shared\TextTemplating\10.0\texttransform.exe";
$solutionDir = Resolve-Path "$scriptDir\..\"

$templates = @(dir "$scriptDir\Database Objects\load\*.tt")

# Cloning to temp dir originally caused issues, because I use the file name in the template (doh!)
# Now I copy to temp dir under the same name
pushd $scriptDir;
try{
foreach($template in $templates){
$templateTemp = Join-Path ([IO.Path]::GetTempPath()) $template.Name;
$targetfile = [IO.Path]::ChangeExtension($template.FullName, '.sql');
Write-Host "Running $($template.Name)"
Write-Host "...output to $targetFile";

# When run from outside VisualStudio you can't use $(SolutionDir)
# ...so have to modify the template to get this to work...
# ...do this by cloning to a temp file, and running this instead
Get-Content $template.FullName | % {
$_.Replace('$(SolutionDir)',"$solutionDir")
} | Out-File -FilePath:$templateTemp

try{
& $t4 $templateTemp -out $targetfile -I $template.DirectoryName;
}finally{
if(Test-Path $templateTemp){ Remove-Item $templateTemp; }
}
}
}finally{
popd;
}

关于.net - 通过 TextTransform.exe 运行模板时使用 $(SolutionDir),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13805563/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com