TextTransformation.exe (ILSpy を使用) のソース コードを調べてみると、テンプレートを変更しないとこれは不可能だと思います (ただし、解決策はあります)。
ここで最終的に重要なのは、Microsoft.VisualStudio.TextTemplating.Engine.ResolveAssemblyReferences()が呼び出されるテンプレート解析中のステップです。これはITextTemplatingEngineHost.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;
}