MgS*_*Sam 7 .net t4 batch-file visual-studio
我正在尝试让我们的T4模板在构建时运行,而不会在Visual Studio Modeling SDK上添加依赖项.我已成功使用此处显示的批处理文件的变体,但我现在遇到的问题是我的.tt文件使用该$(SolutionDir)变量来引用其他项目(因此现在不编译).
处理这个问题的最佳方法是什么?其他人做了什么?(硬编码绝对路径不是一种选择)
编辑:我看到有-a可以传递给TextTransform.exe 的参数,是否可以使用它来定义$(SolutionDir)?
查看 TextTransformation.exe(使用 ILSpy)的源代码,我认为如果不修改模板,这是不可能的(但我确实有一个解决方案)。
最终我们关心的是模板解析过程中调用Microsoft.VisualStudio.TextTemplated.Engine.ResolveAssemblyReferences() 的步骤。这委托给ITextTemplatedEngineHost.ResolveAssemblyReference()(尽管它首先扩展环境变量)
当从命令行运行模板时,所使用的实现是 CommandLineHost 提供的实现,其实现只是查找参考路径和 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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3980 次 |
| 最近记录: |