2012-12-10 16 views
6

Visual Studio Modelleme SDK'sına bağımlılık eklemeden T4 şablonlarımızın oluşturma zamanında çalışmasını sağlamaya çalışıyorum. here gösterilen toplu iş dosyasının bir varyantını başarılı bir şekilde kullandım, ancak şimdi .t dosyamın diğer projelere başvuruda bulunmak için $(SolutionDir) değişkenini kullanmasıyla ilgili bir sorunum var (ve şimdi derleme değil).

Bunu işlemenin en iyi yolu nedir? Başkaları ne yaptı? (Bir seçenek mutlak yollar değildir Sabit kodlama)

DÜZENLEME: TextTransform.exe geçirilebilir -a argüman olduğu görülüyor , bu $(SolutionDir) tanımlamak için kullanmak mümkündür?

+1

Eğer 'SolutionDir =% CD%' geçerli dizine değişkeni ayarlamak için ayarlanmış denediniz: Burada

piers7 's alarak ve onu değiştirmeye, ortaya çıkan script? – Pawel

+1

Bu işe yaramıyor, -a !! $ (SolutionDir)! C: \ dev \ mysolutionroot – piers7

+0

T4'ün bir Mono bağlantı noktası var. Cevabın kod tabanında bir yerde olup olmadığını merak ediyorum. Bkz. Http://stackoverflow.com/a/1395377/26167 – piers7

cevap

2

Kaynak kodunu TextTransformation.exe'den (ILSpy ile) araştırıyorum. Şablonu değiştirmeden bunun mümkün olduğunu sanmıyorum (ancak bir çözümüm var).

Sonuçta biz burada ne umurumda Microsoft.VisualStudio.TextTemplating.Engine.ResolveAssemblyReferences() denir şablon ayrıştırma sırasında adımdır. ITextTemplatingEngineHost.ResolveAssemblyReference() Bu delegeler

şablon komut satırından çalıştırılan

, uygulama CommandLineHost tarafından sağlandığını kullanılıyor (ilk çevre değişkenleri genişletmek olsa), ve bunun uygulanması basitçe Dosyayı referans yollarda ve GAC'de sağlandığı gibi arar. Dosya adının bu noktada hala $ (SolutionPath) bitine sahip olacağı düşünüldüğünde, asla başarılı olamayacaktır.

Sen TextTransform.exe sizin kendi uygulayabilir, ancak sıfırdan büyük ölçüde başlamak zorunda (veya yansıma kullanın) diye, CommandLineHost iç :-(olduğundan Yoksa potansiyel Mono portu kaldıraç https://stackoverflow.com/a/1395377/26167

Ben aynı durumda kendimi bulmak, çünkü bu konuda mutlu olduğumu söyleyemem ...

Düzenleme: Ancak ... sonuçta tüm yapmanız gereken şablonu değiştirmek olduğundan, Şablonları geçici dizine kopyalamak için bir PowerShell betiğini, $ (SolutionDir) ma'yı manuel olarak genişleterek süreçte cro ve oradan onları yürütmek. Bu sadece iyi çalışmak gibi görünüyor. Soruna projeye

Damla bu (eğer dosya uzantısı değiştirmek isteyebilirsiniz) ve gitmek için iyi olmalıdır:

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

Bunu biraz ayrıntılı olarak açıklayabilir misiniz - projeye bu bir "düşecek"? Bunu yapım öncesi veya sonrası işlemler olarak adlandırır mısınız? –

+0

Yazılan kod, çözüm dir bir klasördür ve TT dosyalarını kendisine göre bulur. Bu yüzden sadece root'daki projeye ekleyin. Bunu komut satırından (PowerShell'de) çalıştırırsınız ve evet - gerekiyorsa bunu önceden oluşturulmuş bir adımda (elle yapabilirim) diyebilirsiniz. – piers7

+0

@ piers7 Paylaşım için teşekkürler. Sabit dosya uzantınızı regex kullanarak tt dosyasının kendisinden çıkarılmış bir uzantıyla değiştirdim ... '$ extension = Select-String -Path $ template.FullName -Pattern '<# @ \ s * output \ s + extension = "(. *)" \ s * #> '| ForEach-Object {$ _. Maçlar.Gruplar [1] .Value} – Hosein

0

Ben piers7 çok benzer bir yaklaşım kullanılır - benim durumumda hariç Aslında * .tt dosyasını aynı dizinde tutmam gerekiyordu (dosyaların göreli yollara dayalı çalışma zamanı araması nedeniyle), ancak dosyanın kendisinin farklı adlandırılmış olması umursamadı. Bu şekilde, templateTemp'ın geçici bir dosyada geçici bir dosya oluşturması yerine, aynı klasörde tuttum.

Ayrıca, çözüm dizininin herhangi bir yerinde * .tt dosyalarını tekrar tekrar aramak zorundaydım.

<# 
.Synopsis 
Executes all the T4 templates within designated areas of the containing project 
#> 
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\12.0\texttransform.exe"; 
$solutionDir = Resolve-Path "$scriptDir\" 
$templates = Get-ChildItem -Path $scriptDir -Filter *.tt -Recurse 
$extension = '.ts'; 

pushd $scriptDir; 
try{ 
    foreach($template in $templates){ 
     # keeping the same path (because my template references relative paths), 
     # but copying under different name: 
     $templateTemp = $template.FullName + "____temporary" 
     $targetfile = [IO.Path]::ChangeExtension($template.FullName, $extension); 
     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; 
} 
İlgili konular