รับ Visual Studio เพื่อเรียกใช้เทมเพลต T4 ในทุกบิลด์


163

ฉันจะรับเท็มเพลต T4 เพื่อสร้างเอาต์พุตในทุกบิลด์ได้อย่างไร? ตามที่เป็นอยู่ตอนนี้มันจะสร้างใหม่เฉพาะเมื่อฉันทำการเปลี่ยนแปลงแม่แบบ

ฉันพบคำถามอื่นที่คล้ายคลึงกับสิ่งนี้:

การแปลง T4 และสร้างคำสั่งใน Visual Studio (ไม่มีคำตอบ)

วิธีรับไฟล์ t4 เพื่อสร้างใน visual studio? (คำตอบนั้นไม่ละเอียดพอ [ในขณะที่ยังซับซ้อนอยู่มาก] และยังไม่เข้าใจเลย)

จะต้องมีวิธีที่ง่ายกว่านี้!


ในขณะที่ฉันค่อนข้างจะสนใจที่จะได้ยินคำตอบสำหรับเรื่องนี้ แต่สถานการณ์ของคุณคืออะไร โดยปกติเอาต์พุตของเทมเพลตควรเป็นฟังก์ชันของอินพุตเท่านั้นดังนั้นการสร้างการเปลี่ยนแปลงจึงเป็นเรื่องปกติ
Pavel Minaev

6
แม่แบบของฉันใช้การสะท้อนเพื่อตรวจสอบชุดประกอบอื่น ๆ ซึ่งอาจมีการเปลี่ยนแปลงตั้งแต่งานสร้างครั้งล่าสุด
JoelFan

สิ่งที่เกี่ยวกับความคิดนี้: stackoverflow.com/questions/1649649/…
JoelFan

แม่แบบของฉันมีจุดประสงค์เดียวบันทึกเวลาวันที่สร้าง
Scott Solmer

คำตอบ:


68

ฉันใช้คำตอบของโจเอลแฟนขึ้นมาด้วยสิ่งนี้ ฉันชอบมันมากขึ้นเพราะคุณไม่ต้องจำไว้ว่าจะแก้ไขเหตุการณ์ที่สร้างไว้ล่วงหน้าทุกครั้งที่คุณเพิ่มไฟล์. tt ใหม่ลงในโครงการ

  • เพิ่ม TextTransform.exe ของคุณ %PATH%
  • สร้างไฟล์แบตช์ชื่อ transform_all.bat (ดูด้านล่าง)
  • สร้างกิจกรรมก่อนสร้าง " transform_all ..\.."

transform_all.bat

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION

:: set the working dir (default to current dir)
set wdir=%cd%
if not (%1)==() set wdir=%1

:: set the file extension (default to vb)
set extension=vb
if not (%2)==() set extension=%2

echo executing transform_all from %wdir%
:: create a list of all the T4 templates in the working dir
dir %wdir%\*.tt /b /s > t4list.txt

echo the following T4 templates will be transformed:
type t4list.txt

:: transform all the templates
for /f %%d in (t4list.txt) do (
set file_name=%%d
set file_name=!file_name:~0,-3!.%extension%
echo:  \--^> !file_name!    
TextTransform.exe -out !file_name! %%d
)

echo transformation complete

28
ทางออกที่ดี ฉันต้องการวางเส้นทางแบบเต็มไปที่ TextTransform.exe ( "%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\texttransform.exe") ในไฟล์แบตช์แทนที่จะเพิ่มไปยัง% PATH%
Adam Nofsinger

20
ตัวแปรที่ดีกว่าคือ% COMMONPROGRAMFILES (x86)% แทนที่จะเป็น% COMMONPROGRAMFILES% เพราะมันจะทำงานบนระบบ 64 บิตเช่นกัน
Durden81

3
%COMMONPROGRAMFILES(x86)%\microsoft shared\TextTemplating\11.0\TextTransform.exeดังนั้นเส้นทางแบบเต็มจะเป็น ล้อมด้วยเครื่องหมายคำพูดคู่
northben

1
@ piers7: ฉันอัปเดตรหัสเพื่อตรวจจับ 'bitness' ของระบบปฏิบัติการที่ใช้งานสคริปต์โดยอัตโนมัติ ฉันได้รวมความคิดเห็นของนอร์ ธ เบ็นไว้แล้วเพื่อข้ามไดเรกทอรี obj และนำการตั้งค่าของ Adam Nofsinger ไปใช้เมื่อไม่แก้ไขตัวแปรสภาพแวดล้อม% PATH%
Alex Essilfie

1
IMHO ต้องเตรียมเส้นทางที่จะTextTransform.exeดูด คุณสามารถคลิกขวาที่ "เรียกใช้เครื่องมือกำหนดเอง" ใน Visual Studio ได้แล้วจึงมีเส้นทางของเครื่องมืออยู่แล้ว เหตุใดฉันต้องผ่านการให้บริการอีกครั้งเมื่อฉันสร้างจากบริบทของ Visual Studio
Jez

70

ฉันเห็นด้วยกับ GarethJ - ใน VS2010 มันง่ายมากที่จะสร้างเทมเพลต tt ใหม่ในแต่ละบิลด์ บล็อกของ Oleg Sych อธิบายวิธีการทำ ในระยะสั้น:

  1. ติดตั้งVisual Studio SDK
  2. ติดตั้งVisual Studio 2010 แบบจำลองและ Visualization SDK
  3. เปิดในไฟล์โปรเจ็กต์ text editor และเพิ่มในตอนท้ายของไฟล์ แต่ก่อน </Project>

แค่นั้นแหละ. เปิดโครงการของคุณ แต่ละเทมเพลตบิวด์ * .tt ทั้งหมดจะถูกประมวลผลอีกครั้ง

<!-- This line could already present in file. If it is so just skip it  -->
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- process *.tt templates on each build  -->
<PropertyGroup>
    <TransformOnBuild>true</TransformOnBuild>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets" />

2
นี่คือลิงก์ไปยังโพสต์บล็อกของ Oleg Sych: olegsych.com/2010/04/understanding-t4-msbuild-integration
PhilChuang

4
นี่เป็นทางออกที่ดีมาก อย่างไรก็ตามมีวิธีในการทำให้สิ่งนี้ทำงานโดยไม่ต้องติดตั้ง SDK หรือไม่? ฉันพยายามทำให้มันทำงานได้โดยการคัดลอกไฟล์. target และแอสเซมบลีที่เกี่ยวข้อง แต่ไม่ประสบความสำเร็จ
grimus

3
Chirpy ดูเหมือนจะทำงานได้โดยไม่ต้องดาวน์โหลด SDK ใด ๆ ... อย่างไรก็ตามคุณยังต้องดาวน์โหลดและกำหนดค่า Chirpy ฉันยังคงพยายามค้นหาวิธีแก้ปัญหาที่ทำงานบนการติดตั้งเริ่มต้นของ VS2010 และจะสามารถใช้งานได้ผ่านแหล่งเก็บข้อมูลต้นทางเพื่อให้นักพัฒนาจำเป็นต้องตรวจสอบ repo เพื่อให้ทำงานได้ โซลูชันอื่นทั้งหมดเหล่านี้ต้องการความสนใจต่อผู้พัฒนามากเกินไป
เมียร์

1
หากคุณสร้างโครงการของคุณโดยใช้ MSBuild รุ่น x64 - คุณจะได้รับข้อผิดพลาดนี้: 'MSB4019: โครงการที่นำเข้า "C: \ Program Files (x86) \ MSBuild \ Microsoft \ VisualStudio \ TextTemplating \ v10.0 \ Microsoft.TextTemplating.targets "ไม่พบ ' ความผิดพลาด วิธีแก้ปัญหา - แทนที่ตัวแปร $ (MSBuildExtensionsPath) ด้วย $ (MSBuildExtensionsPath32) ในไฟล์โครงการ
สนิม

3
นอกจากนี้คุณไม่จำเป็นต้องแก้ไขไฟล์. csproj จากบรรทัดคำสั่งเรียกสิ่งที่ต้องการ msbuild mySolution.sln /p:CustomAfterMicrosoftCommonTargets="C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\TextTemplating\Microsoft.TextTemplating.targets" /p:TransformOnBuild=true /p:TransformOutOfDateOnly=false
Giulio Vian

29

มีแพ็คเกจ NuGet ที่ยอดเยี่ยมที่ทำสิ่งนี้:

PM> Install-Package Clarius.TransformOnBuild

รายละเอียดเกี่ยวกับแพคเกจสามารถพบได้ที่นี่


2
มีส้อม 'อย่างไม่เป็นทางการ' คือnuget.org/packages/Clarius.TransformOnBuild-unofficialที่สนับสนุนการcontentสร้างการกระทำ
Erno

1
มันเป็นส่วนขยายที่ดี แต่มันกำลังเรียกใช้ TextTransform.exe ในโหมด commandLine ดังนั้นhostspecific = funcions "จริง"จะไม่ทำงาน
Gh61

1
@JenishRabadiya เพิ่มบรรทัดนี้ไปยังด้านบนสุดของเทมเพลต:<#@ template language="C#" #>
Peter van Kekem

2
ดูเหมือนว่าแพคเกจนี้ได้รับการปรับปรุงเพื่อรองรับhostspecific = "true"และปัญหาอื่น ๆ (8 วันที่ผ่านมา)
Mingwei Samuel

1
การดำเนินการสร้างเนื้อหากำลังทำงานกับเวอร์ชันล่าสุด
androbin

20

ฉันใช้คำตอบของ MarkGr และพัฒนาวิธีแก้ปัญหานี้ ขั้นแรกให้สร้างแบตช์ไฟล์ชื่อRunTemplate.batในโฟลเดอร์เครื่องมือแยกต่างหากเหนือโฟลเดอร์โซลูชันหลัก ไฟล์แบตช์มีเพียงบรรทัด:

"%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\texttransform.exe" -out %1.cs -P %2 -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" %1.tt

ไฟล์แบตช์นี้ใช้พารามิเตอร์ 2 ตัว ... % 1เป็นพา ธ ไปยังไฟล์. tt โดยไม่ต้องมีนามสกุล. tt % 2เป็นเส้นทางไปยัง DLLs ใด ๆ ที่อ้างถึงโดยคำสั่งAssemblyในแม่แบบ

จากนั้นไปที่คุณสมบัติโครงการของโครงการที่มีแม่แบบ T4 ไปที่Build Eventsและเพิ่มบรรทัดคำสั่ง Pre-build เหตุการณ์ต่อไปนี้:

$(SolutionDir)..\..\tools\RunTemplate.bat $(ProjectDir)MyTemplate $(OutDir)

แทนที่MyTemplateด้วยชื่อไฟล์ของไฟล์. tt (เช่น MyTemplate.tt) โดยไม่มีนามสกุล. ttt สิ่งนี้จะมีผลลัพธ์ของการขยายเทมเพลตเพื่อผลิต MyTemplate.cs ก่อนที่จะสร้างโครงการ จากนั้นบิลด์จริงจะคอมไพล์ MyTemplate.cs


แม้ว่าฉันจะยังคงมีปัญหา: stackoverflow.com/questions/1669893/…
JoelFan

1
อย่าลืมเครื่องหมายคำพูดรอบ ๆ $ (SolutionDir) .. \ .. \ tools \ RunTemplate.bat
Ewald Hofman

14

เมื่อเร็ว ๆ นี้พบปลั๊กอิน VS ดีแจ่มใส

มันไม่เพียงสร้าง T4 ของคุณบนบิลด์เท่านั้น แต่ยังอนุญาตให้ใช้วิธีที่ใช้ T4 เพื่อลดขนาดจาวาสคริปต์ CSS และแม้แต่ให้คุณใช้ไวยากรณ์น้อยกว่าสำหรับ CSS ของคุณ


13

น่าจะเป็นวิธีที่ง่ายที่สุดคือการติดตั้งส่วนขยายของ Visual Studio เรียกAutoT4

มันรันเทมเพลต T4 ทั้งหมดในการสร้างโดยอัตโนมัติ


ตกลงกัน! สามารถกำหนดค่าได้และทำงานกับ VS 2015 มันยังรองรับการใช้ EnvDTE ชุดประกอบ (สำหรับการรับการกำหนดค่าการสร้าง) ซึ่งไม่ได้ใช้วิธีการทั้งหมด ข้อเสียเพียงอย่างเดียวคือสมาชิกทุกคนในทีมต้องติดตั้งส่วนขยาย
Gyromite

12

การสร้างล่วงหน้าสามารถลดเป็นบรรทัดเดียว:

forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c echo Transforming @path && \"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"

สิ่งนี้จะแปลง.ttไฟล์ทั้งหมดในโครงการและแสดงรายการเหล่านั้นไปยังเอาต์พุตของบิลด์

หากคุณไม่ต้องการสร้างผลลัพธ์จากนั้นคุณต้องหลีกเลี่ยง"พฤติกรรมที่น่าสนใจ" :

forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c @\"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"

แน่นอนคุณสามารถดึงสิ่งนี้ออกเป็นไฟล์แบตช์ที่คุณผ่านเส้นทางไดเรกทอรีโครงการหากคุณต้องการ

NBเส้นทางอาจต้องมีการปรับแต่ง เส้นทางด้านบนคือตำแหน่งที่ VS 2008 ติดตั้งไว้ในเครื่องของฉัน แต่คุณอาจพบว่าหมายเลขเวอร์ชันระหว่างTextTemplatingและTextTransform.exeแตกต่างกัน


@SprintStar หากคุณมี VS 2012 อาจเป็นวิธีที่ดีกว่าในการทำเช่นนั้น คำตอบอื่น ๆ พูดถึงวิธีที่ดีกว่าที่มีอยู่แล้วสำหรับ VS 2010
Peter Taylor

นี่เป็นวิธีที่ดีที่สุดเพราะฉันไม่ต้องติดตั้งอะไรเลย
Ryan Gates

1
เห็นไม่มี 1.2 แต่มี 12.0 ดังนั้นเปลี่ยนเป็น แต่ได้รับข้อผิดพลาดนี้:System.Exception: T4MVC can only execute through the Visual Studio host
colmde

1
เพียงแค่ต้องอัปเดตพา ธ ของโฟลเดอร์เพื่อใช้ 14.0 แทนที่จะเป็น 1.2 และไปได้ดี
ปืนพก -pete

นี่เป็นทางออกที่ดีที่สุดในความคิดของฉัน (เพิ่งเปลี่ยน 14.0 ตามที่กล่าวไว้ข้างต้น)
เนลสันโรดริเกซ

9

ตรวจสอบ Shared \ TextTemplating Files \ Microsoft C: \ Program (x86) \ CommonTemplating มี exe บรรทัดคำสั่งในนั้น หรือเขียนงาน MSBuild ด้วยโฮสต์ที่กำหนดเองและทำการแปลงตัวเอง


1
โอ้แม้ว่าคุณสามารถทำสิ่งต่างๆเช่น "devenv / Command TextTransformation.TransformAllTemplates / Command File.Exit MySolution.sln" ในปี 2010 มีแนวโน้มที่จะทำลายเซิร์ฟเวอร์บิลด์เป็นครั้งคราว ทางออกที่ดีที่สุดของคุณคือการเขียนงาน MSBuild กับโฮสต์ที่กำหนดเอง
MarkGr

สำหรับการสร้างเดสก์ท็อปเพียงสร้างแมโครที่ใช้ TransformAllTemplates แล้วสร้าง
MarkGr

7

เมื่อเพิ่มคำตอบของเซทรีโนและโจเอลแฟนฉันก็คิดเรื่องนี้ ด้วยโซลูชันนี้ไม่จำเป็นต้องจำไว้ว่าต้องแก้ไขเหตุการณ์ที่สร้างล่วงหน้าทุกครั้งที่คุณเพิ่มไฟล์. tt ใหม่ให้กับโครงการ

ขั้นตอนการดำเนินงาน

  • สร้างแบทช์ไฟล์ชื่อ transform_all.bat (ดูด้านล่าง)
  • สร้างเหตุการณ์ที่สร้างล่วงหน้าtransform_all.bat "$(ProjectDir)" $(ProjectExt)สำหรับแต่ละโครงการด้วย. tt ที่คุณต้องการสร้าง

transform_all.bat

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION

:: set the correct path to the the app
if not defined ProgramFiles(x86). (
  echo 32-bit OS detected
  set ttPath=%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\
) else (
  echo 64-bit OS detected
  set ttPath=%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\
)

:: set the working dir (default to current dir)
if not (%1)==() pushd %~dp1

:: set the file extension (default to vb)
set ext=%2
if /i %ext:~1%==vbproj (
  set ext=vb
) else if /i %ext:~1%==csproj (
  set ext=cs
) else if /i [%ext%]==[] (
  set ext=vb
)

:: create a list of all the T4 templates in the working dir
echo Running TextTransform from %cd%
dir *.tt /b /s | findstr /vi obj > t4list.txt

:: transform all the templates
set blank=.
for /f "delims=" %%d in (t4list.txt) do (
  set file_name=%%d
  set file_name=!file_name:~0,-3!.%ext%
  echo:  \--^> !!file_name:%cd%=%blank%!
  "%ttPath%TextTransform.exe" -out "!file_name!" "%%d"
)

:: delete T4 list and return to previous directory
del t4list.txt
popd

echo T4 transformation complete


หมายเหตุ

  1. การแปลงข้อความถือว่ารหัสในเท็มเพลต T4 เป็นภาษาเดียวกับประเภทโครงการของคุณ หากกรณีนี้ใช้ไม่ได้กับคุณคุณจะต้องแทนที่$(ProjectExt)อาร์กิวเมนต์ด้วยส่วนขยายของไฟล์ที่คุณต้องการสร้างรหัส

  2. .TTไฟล์จะต้องอยู่ในไดเรกทอรีโครงการมิฉะนั้นจะไม่สร้าง คุณสามารถสร้างไฟล์ TT นอกไดเรกทอรีโครงการโดยระบุเส้นทางที่แตกต่างเป็นอาร์กิวเมนต์แรก ( เช่นแทนที่"$(ProjectDir)"ด้วยเส้นทางที่มีไฟล์ TT)

  3. อย่าลืมตั้งค่าเส้นทางที่ถูกต้องไปยังtransform_all.batไฟล์แบตช์
    ตัวอย่างเช่นฉันวางไว้ในไดเรกทอรีโซลูชันของฉันดังนั้นเหตุการณ์ที่สร้างไว้ล่วงหน้ามีดังนี้"$(SolutionDir)transform_all.bat" "$(ProjectDir)" $(ProjectExt)


ฉันกำลังพยายามใช้วิธีการนี้ แต่ฉันยังคงได้รับข้อผิดพลาดด้วย '\ Common ไม่คาดคิดในเวลานี้' ในผลลัพธ์ของฉัน มันเกิดขึ้นที่บรรทัดนี้: สำหรับ / f "delims =" %% d ใน (t4list.txt) ทำ ... ความคิดใดที่ฉันหายไป
Michael Lewis

@MichaelLewis: ฉันได้ผ่านไฟล์แบทช์หลายครั้งโดยไม่พบสิ่งที่อาจทำให้เกิดข้อผิดพลาด โปรดลองวิธีที่เสนอโดย Seth Renoเพื่อดูว่าจะสร้างข้อผิดพลาดเดียวกันหรือไม่ ในระหว่างนี้คุณช่วยโพสต์t4list.txtไฟล์ของคุณไปที่PasteBin ได้ไหมฉันลองดูว่าข้อผิดพลาดของคุณมาจากที่นั่นหรือไม่
Alex Essilfie

ฉันลองวิธีการของเซทกับปัญหาเดียวกัน ('\ Common ไม่คาดคิดในเวลานี้') ฉันไม่สามารถโพสต์ไฟล์ t4list.txt ได้เนื่องจากข้อ จำกัด ขององค์กร แต่ประกอบด้วยหนึ่งบรรทัดและ \ Common ไม่ปรากฏในพา ธ
Michael Lewis

@MichaelLewis: น่าเสียดายถ้าข้อผิดพลาดของคุณเกิดขึ้นที่for /f "delims=" %%d in (t4list.txt) do (และข้อ จำกัด ขององค์กรทำให้คุณไม่สามารถโพสต์t4list.txtไฟล์ของคุณได้ฉันกลัวว่าจะมีไม่มากที่ฉันสามารถช่วยคุณได้ ฉันอยากช่วยแก้ปัญหานี้ แต่ดูเหมือนว่ามันจะเป็นไปไม่ได้เพราะฉันไม่มีข้อมูลที่จะดำเนินการต่อ ขอให้โชคดีในการแก้ไขปัญหาและโปรดอย่าลืมโพสต์โซลูชันของคุณเมื่อคุณประสบความสำเร็จ
Alex Essilfie

มันเป็นไปได้ที่จะทำเช่นเดียวกันเมื่อttมี(this.Host as IServiceProvider).GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;? โชคไม่ดีที่ฉันได้รับข้อยกเว้นอ้างอิงเป็นโมฆะเมื่อฉันเรียกใช้ttจากภายในสตูดิโอภาพ
Andrey K.

6

หากคุณใช้ Visual Studio 2010 คุณสามารถใช้ Visual Studio Modeling และ Visualization SDK ได้: http://code.msdn.microsoft.com/vsvmsdk

สิ่งนี้มีภารกิจ msbuild สำหรับการดำเนินการเท็มเพลต T4 ณ เวลาบิลด์

ดูที่บล็อกของ Oleg สำหรับคำอธิบายเพิ่มเติม: http://www.olegsych.com/2010/04/understanding-t4-msbuild-integration


4

สวัสดีสคริปต์ของฉันยังสามารถแยกวิเคราะห์ส่วนขยายผลผลิต

for /r %1 %%f in (*.tt) do (
 for /f "tokens=3,4 delims==, " %%a in (%%f) do (
  if %%~a==extension "%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\texttransform.exe" -out %%~pnf.%%~b -P %%~pf -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" %%f
 )
)
echo Exit Code = %ERRORLEVEL%

เพียงแค่transform_all.bat $(SolutionDir)สร้างเหตุการณ์ก่อนสร้างและไฟล์ * .tt ทั้งหมดในโซลูชันของคุณจะถูกแปลงโดยอัตโนมัติ


3

Dynamo.AutoTT จะทำสิ่งที่คุณต้องการ คุณสามารถกำหนดค่าให้ดูไฟล์ผ่าน regex หรือสร้างบนบิลด์ นอกจากนี้ยังอนุญาตให้คุณระบุเทมเพลต T4 ที่คุณต้องการเรียกใช้

คุณสามารถดาวน์โหลดได้จากที่นี่: https://github.com/MartinF/Dynamo.AutoTT

เพียงสร้างมันคัดลอกไฟล์ dll และ AddIn ลงไป

C: \ Users \ Documents \ Visual Studio 2012 \ Addins \

และไปคุณไป

หากคุณต้องการให้มันทำงานใน VS2012 คุณจะต้องแก้ไขไฟล์ Dynamo.AutoTT.AddIn และตั้งค่า Version เป็น 11.0 ภายในไฟล์ AddIn;


3

ขอบคุณGitHub.com/Mono/T4ในขณะนี้คุณสามารถทำได้สำหรับทั้ง. NET Core และ Visual Studio builds โดยการเพิ่มสิ่งนี้ลงใน.csprojไฟล์ของคุณ:

  <ItemGroup>
    <DotNetCliToolReference Include="dotnet-t4-project-tool" Version="2.0.5" />
    <TextTemplate Include="**\*.tt" />
  </ItemGroup>

  <Target Name="TextTemplateTransform" BeforeTargets="BeforeBuild">
    <ItemGroup>
      <Compile Remove="**\*.cs" />
    </ItemGroup>
    <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet t4 %(TextTemplate.Identity)" />
    <ItemGroup>
      <Compile Include="**\*.cs" />
    </ItemGroup>
  </Target>

หากคุณแปลงแม่แบบของคุณเป็นภาษาการเขียนโปรแกรมที่แตกต่างกันคุณควรเพิ่มสิ่งที่ชอบ<Compile Remove="**\*.vb" />และ<Compile Include="**\*.vb" />เพื่อให้ได้รับการรวบรวมไฟล์เหล่านี้แม้ว่าคุณจะยังไม่ได้สร้างไฟล์

RemoveและIncludeเคล็ดลับที่จำเป็นสำหรับการสร้างครั้งแรกเท่านั้นหรือคุณสามารถทำให้ XML สั้นลงเช่นนี้

  <ItemGroup>
    <DotNetCliToolReference Include="dotnet-t4-project-tool" Version="2.0.5" />
    <TextTemplate Include="**\*.tt" />
  </ItemGroup>

  <Target Name="TextTemplateTransform" BeforeTargets="BeforeBuild">
    <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet t4 %(TextTemplate.Identity)" />
  </Target>

และเรียกใช้งาน build สองครั้ง (เป็นครั้งแรก) หากคุณได้สร้างไฟล์ที่คอมมิทไปที่ที่เก็บแล้วจะไม่มีปัญหาในการสร้างใหม่ด้วยทั้งสองตัวอย่าง

ใน Visual Studio คุณอาจต้องการเห็นสิ่งนี้:

ป้อนคำอธิบายรูปภาพที่นี่

แทนสิ่งนี้:

ป้อนคำอธิบายรูปภาพที่นี่

ดังนั้นเพิ่มสิ่งนี้ในไฟล์โครงการของคุณ:

  <ItemGroup>
    <Compile Update="UInt16Class.cs">
      <DependentUpon>UInt16Class.tt</DependentUpon>
    </Compile>
    <Compile Update="UInt32Class.cs">
      <DependentUpon>UInt32Class.tt</DependentUpon>
    </Compile>
    <Compile Update="UInt64Class.cs">
      <DependentUpon>UInt64Class.tt</DependentUpon>
    </Compile>
    <Compile Update="UInt8Class.cs">
      <DependentUpon>UInt8Class.tt</DependentUpon>
    </Compile>
  </ItemGroup>

ทำตัวอย่างที่นี่ให้สมบูรณ์: GitHub.com/Konard/T4GenericsExample (รวมถึงการสร้างไฟล์หลายไฟล์จากเทมเพลตเดียว)


1

นี่คือทางออกของฉัน - คล้ายกับคำตอบที่ยอมรับ เรามีปัญหากับการควบคุมแหล่งที่มาของเรา ไฟล์. cs เป้าหมายเป็นแบบอ่านอย่างเดียวและ T4 ล้มเหลว นี่คือรหัสที่เรียกใช้ T4 ในโฟลเดอร์ temp เปรียบเทียบไฟล์เป้าหมายและคัดลอกเฉพาะในกรณีที่มีการเปลี่ยนแปลงเดียวกัน มันไม่ได้แก้ไขปัญหาของไฟล์ read.only แต่อย่างน้อยมันก็ไม่ได้เกิดขึ้นบ่อยมาก:

Transform.bat

ECHO Transforming T4 templates
SET CurrentDirBackup=%CD%
CD %1
ECHO %1
FOR /r %%f IN (*.tt) DO call :Transform %%f
CD %CurrentDirBackup%
ECHO T4 templates transformed
goto End

:Transform
set ttFile=%1
set csFile=%1

ECHO Transforming %ttFile%:
SET csFile=%ttFile:~0,-2%cs
For %%A in ("%ttFile%") do Set tempTT=%TEMP%\%%~nxA
For %%A in ("%csFile%") do Set tempCS=%TEMP%\%%~nxA

copy "%ttFile%" "%tempTT%
"%COMMONPROGRAMFILES(x86)%\microsoft shared\TextTemplating\11.0\TextTransform.exe"  "%tempTT%"

fc %tempCS% %csFile% > nul
if errorlevel 1 (
 :: You can try to insert you check-out command here.
 "%COMMONPROGRAMFILES(x86)%\microsoft shared\TextTemplating\11.0\TextTransform.exe"  "%ttFile%"
) ELSE (
 ECHO  no change in %csFile%
)

del %tempTT%
del %tempCS%
goto :eof

:End

คุณสามารถลองเพิ่มคำสั่งเช็คเอาท์บนบรรทัด (:: คุณสามารถลอง .... )

ในโครงการของคุณตั้งค่านี้เป็นการกระทำที่สร้างไว้ล่วงหน้า:

Path-To-Transform.bat "$(ProjectDir)"

1

คุณเพียงแค่ต้องเพิ่มคำสั่งนี้ในเหตุการณ์ที่สร้างไว้ล่วงหน้าของโครงการ:

if $(ConfigurationName) == Debug $(MSBuildToolsPath)\Msbuild.exe  /p:CustomBeforeMicrosoftCSharpTargets="$(ProgramFiles)\MSBuild\Microsoft\VisualStudio\v11.0\TextTemplating\Microsoft.TextTemplating.targets"  $(ProjectPath) /t:TransformAll 

การตรวจสอบการกำหนดค่า = debug ตรวจสอบให้แน่ใจว่าคุณไม่ได้สร้างรหัสในโหมดการปล่อยเมื่อคุณสร้างบิลด์บนเซิร์ฟเวอร์การสร้าง TFS เป็นตัวอย่าง


ดี แต่การเปลี่ยนแปลงทั้งหมดอาจเป็นอันตรายได้หาก T4MVC ไม่เพียง แต่เฉพาะในโครงการและเราไม่ต้องการเรียกใช้ทั้งหมด ...
Landeeyo

3
ฉันไม่มี TextTemplating ในโฟลเดอร์ v11.0 คุณได้สิ่งนั้นมาจากไหน
แซค

1

ใน visual studio 2013 ให้คลิกขวาที่เท็มเพลต T4 และตั้งค่าคุณสมบัติการแปลงบนบิลด์เป็นจริง


1
ฉันไม่พบตัวเลือกนี้ในเมนูคลิกขวาอย่างไรก็ตามตาม MSDN คุณสามารถทำได้โดยแก้ไขไฟล์โครงการใน VS 2012 และ 2013 ดูmsdn.microsoft.com/en-us/library/ee847423 aspxหรือmsdn.microsoft.com/en-us/library/vstudio/ee847423.aspxสำหรับรายละเอียด
yoel halb

สิ่งนี้ดูเหมือนจะเป็นตัวเลือกที่มาพร้อมกับเครื่องมือ T4 ที่จับต้องได้เท่านั้นไม่ใช่ค่าเริ่มต้นใน Visual Studio
Matt DiTrolio

ใช่นี่เป็นเพียงในรุ่นProของ T4 Toolbox
Pompair

1

นี่คือวิธีที่ฉันจับมัน ลิงค์ โดยทั่วไปการสร้างบล็อกที่ยอดเยี่ยม (blogs.clariusconsulting.net/kzu/how-to-transform-t4-templates-on-build-without-installing-a-visual-studio-sdk/ ไม่สามารถโพสต์เพิ่มเติมได้ที่ 2 ลิงค์ :() ฉันมาด้วยไฟล์. targetsนี้สำหรับใช้กับไฟล์ visual studio proj

มันมีประโยชน์เมื่อคุณใช้ dll-s อื่น ๆ ใน. ttt ของคุณและคุณต้องการให้ผลลัพธ์เปลี่ยนไปเมื่อ dll-s กำลังเปลี่ยนแปลง

มันทำงานอย่างไร:

  1. สร้าง tt เพิ่มชื่อชุดประกอบ = "$ (SolutionDir) path \ to \ other \ project \ output \ foo.dll และตั้งค่าการแปลงและผลลัพธ์ให้เป็นไปตามที่คาดไว้
  2. เอาการอ้างอิงแอสเซมบลีออกจาก. tt

  3. ภายในไฟล์ proj ใช้รหัสนี้เพื่อตั้งค่าการแปลงในการสร้าง:

    <PropertyGroup>
      <!-- Initial default value -->
      <_TransformExe>$(CommonProgramFiles)\Microsoft Shared\TextTemplating\10.0\TextTransform.exe</_TransformExe>
      <!-- If explicit VS version, override default -->
      <_TransformExe Condition="'$(VisualStudioVersion)' != ''">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\TextTransform.exe</_TransformExe>
      <!-- Cascading probing if file not found -->
      <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\10.0\TextTransform.exe</_TransformExe>
      <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\11.0\TextTransform.exe</_TransformExe>
      <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\12.0\TextTransform.exe</_TransformExe>
      <!-- Future proof 'til VS2013+2 -->
      <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\13.0\TextTransform.exe</_TransformExe>
      <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\14.0\TextTransform.exe</_TransformExe>
      <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\15.0\TextTransform.exe</_TransformExe>
    
      <IncludeForTransform>@(DllsToInclude, '&amp;quot; -r &amp;quot;')</IncludeForTransform>
    </PropertyGroup>
    • ส่วนแรกหา TextTransform.exe

    • $(IncludeForTransform)จะเท่ากับc:\path\to\dll\foo.dll' -r c:\path\to\dll\bar.dllเนื่องจากเป็นวิธีเพิ่มการอ้างอิงสำหรับ TextTransform ในบรรทัดคำสั่ง

       <Target Name="TransformOnBuild" BeforeTargets="BeforeBuild">
         <!--<Message Text="$(IncludeForTransform)" />-->
         <Error Text="Failed to find TextTransform.exe tool at '$(_TransformExe)." Condition="!Exists('$(_TransformExe)')" />
         <ItemGroup>
           <_TextTransform Include="$(ProjectDir)**\*.tt" />
         </ItemGroup>
         <!-- Perform task batching for each file -->
         <Exec Command="&quot;$(_TransformExe)&quot; &quot;@(_TextTransform)&quot; -r &quot;$(IncludeForTransform)&quot;" Condition="'%(Identity)' != ''" />
       </Target>
    • <_TextTransform Include="$(ProjectDir)**\*.tt" />สิ่งนี้จะสร้างรายการไฟล์ tt ทั้งหมดภายในโครงการและไดเรกทอรีย่อย

    • <Exec Command="... สร้างบรรทัดสำหรับแต่ละไฟล์. tT ที่พบซึ่งมีลักษณะดังนี้ "C:\path\to\Transform.exe" "c:\path\to\my\proj\TransformFile.tt" -r"c:\path\to\foo.dll" -r "c:\path\to\bar.dll"

  4. สิ่งเดียวที่ต้องทำคือเพิ่มเส้นทางไปยังที่กำลังใน:

        <ItemGroup>
          <DllsToInclude Include="$(ProjectDir)path\to\foo.dll">
            <InProject>False</InProject>
          </DllsToInclude>
          <DllsToInclude Include="$(ProjectDir)path\to\bar.dll">
            <InProject>False</InProject>
          </DllsToInclude>
        </ItemGroup>

    ที่นี่<InProject>False</InProject>ซ่อนรายการเหล่านี้จากมุมมองโซลูชัน

ดังนั้นตอนนี้คุณควรจะสามารถสร้างรหัสของคุณในการสร้างและการเปลี่ยนแปลงของ dll-s

คุณสามารถลบเครื่องมือที่กำหนดเอง (จากคุณสมบัติภายใน Visual Studio) เพื่อให้ VS ไม่พยายามแปลงและล้มเหลวอย่างน่าสังเวชทุกครั้ง เนื่องจากเราลบการอ้างอิงชุดประกอบในขั้นตอนที่ 2


โปรดเพิ่มโซลูชันลงในคำตอบของคุณเพื่อให้บริบทเพิ่มเติม ลิงค์ไม่ใช่คำตอบสำหรับคำถามและอาจจะตายเมื่อผู้ใช้รายอื่นกลับมาที่คำถามนี้ในภายหลัง
Frank van Wijk


1

คุณเพิ่งติดตั้งแพคเกจNuGet : Clarius.TransformOnBuild

จากนั้นทุกครั้งที่คุณคลิกสร้างโครงการ (หรือโซลูชัน) ไฟล์. ttของคุณจะทำงาน


1

ใน Visual Studio 2017 (อาจเป็นเวอร์ชั่นถัดไป) คุณควรเพิ่มสิ่งนี้ในเหตุการณ์ก่อนสร้าง:

"$(DevEnvDir)TextTransform.exe" -out "$(ProjectDir)YourTemplate.cs" "$(ProjectDir)YourTemplate.tt"

ps เปลี่ยนพา ธ ไปยังเทมเพลตของคุณหากมันไม่ได้อยู่ในไดเรกทอรีโครงการราก


0

ผู้ชายบางคนสร้างแพ็คเกจ nugetสำหรับสิ่งนี้

หมายเหตุด้านข้าง: ฉันได้รับข้อผิดพลาดในการคอมไพล์จาก TextTemplate.exe และแพ็คเกจ (เพราะแพ็คเกจนั้นเรียกว่า TextTemplate.exe) แต่ไม่ใช่จาก Visual Studio เห็นได้ชัดว่าพฤติกรรมนั้นไม่เหมือนกัน หัวขึ้น

แก้ไข: นี่คือปัญหาของฉัน


0

นี่คือเหตุการณ์ที่สร้างไว้ล่วงหน้าโดยใช้ Microsoft Tooling และพา ธ มาตรฐานเท่านั้น มันทดสอบใน vs2019 / netcore3.1

แทนที่ "AppDbContext.tt" ด้วยพา ธ ไฟล์ที่สัมพันธ์กับโครงการของคุณ:

"$(MSBuildBinPath)\msbuild" $(SolutionPath) /t:$(ProjectName):Transform /p:TransformFile="AppDbContext.tt" /p:CustomAfterMicrosoftCommonTargets="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TextTemplating\Microsoft.TextTemplating.targets"

Microsoft ยังมีแนวทางในการทำให้มาโครเช่น "$ (SolutionDirectory)" พร้อมใช้งานในเทมเพลตโดยใช้T4ParameterValuesในไฟล์โครงการของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.