วิธีการเรียกใช้เหตุการณ์การโพสต์บิลด์ Visual Studio สำหรับการตรวจแก้จุดบกพร่องสร้างเท่านั้น


592

ฉันจะ จำกัด กิจกรรม post-build ของฉันให้ทำงานเฉพาะสำหรับ build หนึ่งประเภทได้อย่างไร

ฉันกำลังใช้กิจกรรมเพื่อคัดลอกไฟล์ DLL ไปยังไดเรกทอรีเสมือน IIS ในเครื่อง แต่ฉันไม่ต้องการให้สิ่งนี้เกิดขึ้นบนเซิร์ฟเวอร์การสร้างในโหมดรีลีส

คำตอบ:


746

กิจกรรมก่อนและหลังสร้างบิลด์จะทำงานเป็นสคริปต์ชุดงาน $(ConfigurationName)คุณสามารถทำคำสั่งเงื่อนไขใน

ตัวอย่างเช่น

if $(ConfigurationName) == Debug xcopy something somewhere

7
แปลกอาจจะเพียงแค่ฉัน แต่ฉันพยายามเพิ่มถ้าเงื่อนไขและตอนนี้ฉันได้รับข้อผิดพลาดนี้ - ข้อผิดพลาดออกด้วยรหัส 255
ไมเคิล L

101
ฉันพบว่าความต้องการคำสั่งทั้งหมดจะอยู่ในบรรทัดเดียวหรือคุณจะได้รับ "ออกด้วยรหัส 255"
โรบินมินโตะ

7
คุณยังสามารถใช้ gotos / ฉลากสำหรับการแก้ปัญหาฟูลเลอร์ (ดูของฉัน 24 กรกฎาคม answwer)
CestLaGalere

11
และคุณสามารถใช้วงเล็บด้วยถ้าคำสั่ง (ดูคำตอบของฉันสำหรับตัวอย่าง)
gbjbaanb

1
คุณควรใช้ "xcopy / Y" เพื่อให้ไฟล์นั้นถูกเขียนทับในไดเรกทอรีเป้าหมาย
Matthias

521

FYI คุณไม่จำเป็นต้องใช้ goto คำสั่งshell IFสามารถใช้กับวงเล็บเหลี่ยมได้:

if $(ConfigurationName) == Debug (
  copy "$(TargetDir)myapp.dll" "c:\delivery\bin" /y
  copy "$(TargetDir)myapp.dll.config" "c:\delivery\bin" /y
) ELSE (
  echo "why, Microsoft, why".
)

62
ฉันยังอาจเพิ่มจะต้องระวังวงเล็บเปิดที่ต้องปฏิบัติตามคำสั่ง if ทันทีเช่นถ้ามันอยู่ในบรรทัดถัดไปรหัสข้อผิดพลาดจะมีการผลิต
wonea

37
ใช้"$(ConfigurationName)"(สังเกตเครื่องหมายคำพูด) หากคุณได้รับรหัสข้อผิดพลาด 255
jgauffin

20
หมายเหตุถ้าคุณใช้ "" รอบ ๆ $ (ConfigurationName) คุณต้องใส่เครื่องหมายอัญประกาศด้วยคำว่า Debug เช่นกัน - คำสั่ง shell คำสั่ง IF นั้นมีความหมายมาก .. จริงๆ ... เมื่อพูดถึงการเปรียบเทียบสตริง
gbjbaanb

5
หมายเหตุเพื่อกำจัด 255 ฉันต้องใช้ "" รอบ ๆ $ (ConfigurationName) และลบช่องว่างรอบเงื่อนไขตัวอย่างเช่นถ้า "$ (ConfigurationName)" == "Release" <- ไม่มีช่องว่างรอบ ๆ ==
fhilton

15
ในกรณีของฉันกับ Visual Studio 2017 $(ConfigurationName)นั้นว่างเปล่า (บรรทัดคำสั่งเหตุการณ์หลังสร้าง) if "$(Configuration)" == "Debug"ทำงานให้ฉัน BTW ถ้าคุณต้องการที่จะทำบางสิ่งบางอย่างในการกำหนดค่าอื่น ๆ if NOT "$(Configuration)" == "Debug"ทั้งหมดการใช้งาน
Ralf Hundewadt

125

เพิ่มกิจกรรมสร้างโพสต์ของคุณเหมือนปกติ จากนั้นบันทึกโครงการของคุณเปิดในNotepad (หรือตัวแก้ไขรายการโปรดของคุณ) และเพิ่มเงื่อนไขให้กับกลุ่มคุณสมบัติ PostBuildEvent นี่คือตัวอย่าง:

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <PostBuildEvent>start gpedit</PostBuildEvent>
</PropertyGroup>

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

3
ฉันต้องบอกว่านี่เป็นคำตอบที่ดีกว่าสำหรับฉันวิธีที่ต้องการใช้ไม่ได้ผล
Michael L

8
คุณไม่จำเป็นต้องเปิดใน Notepad คุณสามารถอยู่ใน Visual Studio ได้ คุณสามารถคลิกขวาที่ไฟล์โครงการคลิก "ยกเลิกการโหลดโครงการ" จากนั้นคลิกขวาอีกครั้งและคลิก "แก้ไข" ตอนนี้คุณสามารถแก้ไขไฟล์ {{csproj}} ด้วยการระบายสีไวยากรณ์ คลิกขวาอีกครั้ง แต่คลิก "โหลดซ้ำโครงการ" เพื่อโหลดซ้ำ
Abel

1
วิธีนี้ไม่ได้ขยายมาโครในคำสั่ง PostBuildEvent เองเมื่อฉันลอง ขยายไปสู่cd "$(ProjectDir)" cd ""
Darryl

3
ใน VS 2017 <Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$(ConfigurationName) == Debug"> <Exec Command="your command"/></Target>คุณยังสามารถทำเช่นนี้กับ ตัวแปรมาโครและทุกอย่างทำงานได้ตามปกติ
SC

106

อีกทางเลือกหนึ่ง (เนื่องจากเหตุการณ์ถูกใส่ลงในไฟล์แบตช์แล้วเรียกว่า) ให้ใช้สิ่งต่อไปนี้ (ในกล่องสร้างเหตุการณ์ไม่ใช่ในไฟล์แบตช์):

if $(ConfigurationName) == Debug goto :debug

:release
signtool.exe ....
xcopy ...

goto :exit

:debug
' Debug items in here

:exit

วิธีนี้คุณสามารถมีกิจกรรมสำหรับการกำหนดค่าใด ๆ และยังคงจัดการกับแมโครแทนที่จะต้องผ่านพวกเขาลงในแฟ้มชุดจำได้ว่า%1เป็น$(OutputPath)ฯลฯ


6
หากคุณได้รับโอกาสที่จะดูรหัสบางส่วนในตัวสะท้อนสัญญาณคอมไพเลอร์จะแปลงคำสั่ง switch / case จำนวนมากให้กลายเป็น goto
StingyJack

10
คอมไพเลอร์ส่วนใหญ่แปลโค้ดเป็นคำแนะนำที่ง่ายกว่าเช่น goto และวิศวกรรมย้อนกลับไม่สามารถรวบรวมคำสั่งที่ง่ายกว่านี้ไว้ในคำแนะนำที่ซับซ้อนกว่าที่ "ดี" ที่คุณอยากเห็น ฉันไม่เห็นว่า Microsoft บังคับให้เราใช้ goto หรือเกี่ยวข้องกับโพสต์นี้อย่างไร
TamusJRoyce

1
@StingyJack: ถ้าคุณดูโค้ดที่คอมไพล์แล้วคุณจะเห็นว่ามันกลายเป็นคำสั่ง JMP :) ฉันไม่สนใจว่าคอมไพเลอร์จะทำอะไรภายใต้หน้าปกตราบใดที่ฉันเขียนโค้ดที่อ่านได้ดี (ไม่ว่าการใช้ข้ามไปไม่ได้บางครั้งมากง่ายต่อการอ่าน)
gbjbaanb

ถ้าฉันวางคำสั่ง post-build ไว้ในแบตช์ฉันจะได้รับข้อความแสดงข้อผิดพลาดนี้เมื่อกด build:Error 1 The command "C:\MyProject\postbuild.bat" exited with code 99. MyProject
Sebastian

4
หากคุณต้องการคุณสามารถลบifและใช้งานได้goto :$(ConfigurationName)
Calimero100582

15

Visual Studio 2015: ไวยากรณ์ที่ถูกต้องคือ (เก็บไว้ในหนึ่งบรรทัด):

if "$(ConfigurationName)"=="My Debug CFG" ( xcopy "$(TargetDir)test1.tmp" "$(TargetDir)test.xml" /y) else ( xcopy "$(TargetDir)test2.tmp" "$(TargetDir)test.xml" /y)

ไม่มีข้อผิดพลาด 255 ที่นี่


3
เก็บไว้ในบรรทัดเดียว
Eric Bole-Feysot

ทำงานได้ดี Tks
Vinicius Gonçalves

1
เทคนิคตามเงื่อนไขของคุณทำงานได้ดีที่สุดสำหรับฉัน อย่างไรก็ตามวิธีนี้ใช้งานได้ดีกว่าโดยไม่มีเงื่อนไขเลยและมีความรัดกุมมากกว่านี้ คัดลอก "$ (ProjectDir) \ .. \ $ (ConfigurationName) \ MyFileName" "$ (TargetDir)"
shawn1874

1
สคริปต์ของคุณถูกต้อง แต่สคริปต์ของฉันอนุญาตให้คัดลอกไฟล์ต่าง ๆ สำหรับการกำหนดค่าที่แตกต่างกัน
Eric Bole-Feysot

8

ตั้งแต่ Visual Studio 2019 .csprojรูปแบบที่ทันสมัยรองรับการเพิ่มเงื่อนไขโดยตรงในTargetองค์ประกอบ:

<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Debug'">
    <Exec Command="nswag run nswag.json" />
</Target>

UI ไม่มีวิธีในการตั้งค่านี้ แต่ดูเหมือนว่าจะออกจากConfigurationแอตทริบิวต์อย่างปลอดภัยหากคุณทำการเปลี่ยนแปลงผ่าน UI


สิ่งนี้ใช้ได้กับฉันในปี 2019 ขอบคุณ!
BrandoTheBrave

สิ่งนี้สมควรที่จะสูงขึ้นอีกทั้งควรอัปเดต UI เพื่อให้คุณทำเครื่องหมายการกำหนดค่าการสร้างหรืออย่างน้อยก็เพิ่มเงื่อนไขจากคุณสมบัติ csproj
DeadlyChambers

4

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

$(ConfigurationName)ส่งชื่อการกำหนดค่าที่มี

ตรวจสอบว่ามันขึ้นอยู่กับวิธีที่คุณใช้ขั้นตอนหลังการสร้าง - มันจะเป็นอาร์กิวเมนต์บรรทัดคำสั่ง


-1

สิ่งนี้ใช้ได้กับฉันใน Visual Studio 2015

ฉันคัดลอกไฟล์ DLL ทั้งหมดจากโฟลเดอร์ที่อยู่ในโฟลเดอร์ไลบรารีในระดับเดียวกับโฟลเดอร์โซลูชันของฉันไปยังไดเรกทอรีเป้าหมายของโครงการที่กำลังสร้าง

ใช้เส้นทางสัมพัทธ์จากไดเรกทอรีโครงการของฉันและขึ้นโครงสร้างโฟลเดอร์สองขั้นตอนด้วย .. \ .. \ lib

MySolutionFolder
.... MyProject
Lib

if $(ConfigurationName) == Debug (
xcopy /Y "$(ProjectDir)..\..\lib\*.dll" "$(TargetDir)"
) ELSE (echo "Not Debug mode, no file copy from lib")

-2

เช่นเดียวกับการตั้งค่าโครงการใด ๆ buildevents สามารถกำหนดค่าต่อการกำหนดค่า เพียงเลือกการกำหนดค่าที่คุณต้องการเปลี่ยนแปลงในเมนูดรอปดาวน์ของหน้าคุณสมบัติและแก้ไขขั้นตอนการสร้างโพสต์


10
Build Events ไม่เฉพาะเจาะจงสำหรับการกำหนดค่าใด ๆ เมื่อสร้างใน IDE
โจเซฟไดเกิล

1
ไม่ทำงานใน VS2015 เช่นกัน ไม่สามารถกำหนดค่าได้ต่อการกำหนดค่า
วิลเล็ม

2
ใช้เฉพาะกับโครงการ C ++ ใน Visual Studio ไม่ใช่ C #
bytecode77

-3

ใน Visual Studio 2012 คุณต้องใช้ (ฉันคิดว่าใน Visual Studio 2010 ด้วย)

if $(Configuration) == Debug xcopy

$(ConfigurationName) ถูกระบุว่าเป็นแมโคร แต่ไม่ได้กำหนดไว้

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

เปรียบเทียบ: แมโครสำหรับคำสั่งการสร้างและคุณสมบัติ


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