通过TextTransform.exe使用$(SolutionDir)运行模板时 [英] Using $(SolutionDir) when running template via TextTransform.exe

查看:586
本文介绍了通过TextTransform.exe使用$(SolutionDir)运行模板时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让我们的T4模板在构建时运行,而对Visual Studio的建模SDK添加依赖​​。我已经成功地使用了批处理文件的一个变种这里显示,但我现在有一个问题,我.TT文件使用 $(SolutionDir)变量引用其他项目(因此现在不编译)。

I'm trying to get our T4 templates to run at build time, without adding dependencies on the Visual Studio Modeling SDK. I've successfully used a variant of the batch file shown here, but I now have a problem in that my .tt files use the $(SolutionDir) variable to reference other projects (and thus are now not compiling).

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

What is the best way to handle this? What have other people done? (Hard-coding absolute paths is not an option)

编辑: 我看到有在 -a 可以传递给TextTransform.exe的说法,是有可能使用这种方法来定义 $(SolutionDir)

I see there's the -a argument that can be passed to TextTransform.exe, is it possible to use this to define $(SolutionDir)?

推荐答案

综观从TextTransformation.exe(与ILSpy)源$ C ​​$ C,我不认为这是可能的,而无需修改模板(但我有中的溶液)。

Looking through the source code from TextTransformation.exe (with ILSpy) I don't think this is possible without modifying the template (but I do have a solution).

最后,我们关心的就是把模板解析其中 Microsoft.VisualStudio.TextTemplating.Engine.ResolveAssemblyReferences()被称为中的步骤。这代表为 ITextTemplatingEngineHost.ResolveAssemblyReference()(尽管它首先展开环境变量)

Ultimately what we care about here is the step during the template parsing where Microsoft.VisualStudio.TextTemplating.Engine.ResolveAssemblyReferences() is called. This delegates to ITextTemplatingEngineHost.ResolveAssemblyReference() (though it does expand environment variables first)

在模板从命令行运行,所用的实现是通过在 CommandLineHost 提供,它的实现只是寻找作为参考路径和海关总署提供的文件。鉴于该文件的名称将在这一点上还是有,它永远不会成功。

When the template is run from the command line, the implementation being used is that provided by the CommandLineHost, and its implementation simply looks for the file as supplied in reference paths and the GAC. Given the file name will at this point still have the $(SolutionPath) bit in, it's never going to succeed.

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

You could implement your own version of TextTransform.exe, but you'd have to start largely from scratch (or use reflection), since CommandLineHost is internal :-( Or you could potentially leverage the Mono port http://stackoverflow.com/a/1395377/26167

我不能说我很高兴这一点,因为我发现自己在同一条船上......

I can't say I'm happy about this, because I find myself in the same boat...

编辑:但是......因为最终所有你需要做的是改变模板,我组建了一个PowerShell脚本的模板复制到临时目录,手动扩展$(SolutionDir)宏的过程中,并从那里执行。这似乎工作的就好了的。

However... since ultimately all you need to do is change the template, I put together a PowerShell script to copy the templates to the temp directory, manually expanding the $(SolutionDir) macro in the process, and execute them from there. That seems to work just fine.

下降到这一违规项目(您可能需要更改文件扩展名),你应该是好去:

Drop this into the offending project (you might want to change the file extension) and you should be good to go:

<#
.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;
}

这篇关于通过TextTransform.exe使用$(SolutionDir)运行模板时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆