ใช้ msbuild เพื่อเรียกใช้งาน File System Publish Profile


87

ฉันมีโปรเจ็กต์ ac # .Net 4.0 ที่สร้างด้วย VS2010 และตอนนี้สามารถเข้าถึงได้ด้วย VS2012

ฉันพยายามเผยแพร่เฉพาะไฟล์ที่จำเป็นจากเว็บไซต์นี้ไปยังตำแหน่งปลายทาง(C: \ builds \ MyProject [Files])

โครงสร้างไฟล์ของฉัน: ./ProjectRoot/MyProject.csproj ./ProjectRoot/Properties/PublishProfiles/FileSystemDebug.pubxml

ฉันเรียกใช้สิ่งต่อไปนี้ผ่าน MSBuild:

C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ MSBuild.exe ./ProjectRoot/MyProject.csproj / p: DeployOnBuild = true /p:PublishProfile=./ProjectRoot/Properties/PublishProfiles/FileSystemDebug.pubxml

นี่คือ xml ใน FileSystemDebug.pubxml

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <publishUrl>C:\builds\MyProject\</publishUrl>
    <DeleteExistingFiles>True</DeleteExistingFiles>
  </PropertyGroup>
</Project>

พฤติกรรมที่ได้คือ:

  • ไฟล์ zip ถูกสร้างขึ้นที่นี่: ./ProjectRoot/obj/Debug/Package/MyProject.zip
  • ไม่มีการปรับใช้กับ<publishUrl>C:\builds\MyProject\</publishUrl>WTF
  • ไฟล์ zip ที่สร้างขึ้นเป็นอาหารเช้าแบบหมูและเต็มไปด้วยไฟล์ที่ไม่จำเป็นสำหรับแอปพลิเคชัน

เมื่อฉันเรียกใช้โปรไฟล์การเผยแพร่นี้ผ่านวิชวลสตูดิโอโฟลเดอร์จะถูกสร้างขึ้นที่ * C: \ builds \ MyProject *และมีสิ่งประดิษฐ์ที่แน่นอนที่ฉันต้องการ

ฉันจะได้ผลลัพธ์ง่ายๆจาก msbuild ได้อย่างไร

คำตอบ:


52

FYI: ผมมีปัญหาเดียวกันกับ Visual Studio 2015 msbuild myproject.csproj /p:DeployOnBuild=true /p:PublishProfile=myprofileหลังจากหลายชั่วโมงพยายามตอนนี้ผมสามารถทำได้

ฉันต้องแก้ไขไฟล์. csproj ของฉันเพื่อให้มันใช้งานได้ มีบรรทัดดังนี้:

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" 
  Condition="false" />

ฉันเปลี่ยนบรรทัดนี้ดังนี้:

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v14.0\WebApplications\Microsoft.WebApplication.targets" />

(ฉันเปลี่ยน 10.0 เป็น 14.0 ไม่แน่ใจว่าจำเป็นหรือไม่ แต่ฉันต้องลบส่วนเงื่อนไขออกอย่างแน่นอน)


1
การนำเข้าตามเงื่อนไขที่มีCondition="false"อยู่สำหรับความเข้ากันได้ย้อนหลัง VS2010 กำหนดให้มีการนำเข้านี้แม้ว่าจะถูกข้ามไปเนื่องจากเงื่อนไขที่ไม่ถูกต้องก็ตาม หากคุณดูอีกครั้งคุณจะเห็นว่า csproj มีการนำเข้าอื่น$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targetsซึ่งแก้ไขไปยังไฟล์เป้าหมายสำหรับ Visual Studio เวอร์ชันปัจจุบัน
Steven Liekens

3
หมายเหตุ: การใช้งานเชิงกลยุทธ์ของ$(MSBuildToolsVersion)ในเส้นทางไปยังบัญชีสำหรับรุ่น VS <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(MSBuildToolsVersion)\WebApplications\Microsoft.WebApplication.targets" Condition="false" />ที่เหมาะสม: สิ่งนี้ใช้ได้ผลกับฉันใน VS2015 Update 1
Al Dass

43

พบคำตอบที่นี่: http://www.digitallycreated.net/Blog/59/locally-publishing-a-vs2010-asp.net-web-application-using-msbuild

Visual Studio 2010 มีคุณลักษณะการเผยแพร่โครงการเว็บแอปพลิเคชันใหม่ที่ช่วยให้คุณเผยแพร่โครงการเว็บแอปของคุณได้อย่างง่ายดายด้วยการคลิกปุ่ม เบื้องหลังการแปลง Web.config และการสร้างแพ็กเกจทำได้โดยสคริปต์ MSBuild ขนาดใหญ่ที่นำเข้าสู่ไฟล์โครงการของคุณ (พบได้ที่: C: \ Program Files (x86) \ MSBuild \ Microsoft \ VisualStudio \ v10.0 \ Web \ Microsoft .Web.Publishing.targets) น่าเสียดายที่สคริปต์มีความซับซ้อนอย่างมากยุ่งเหยิงและไม่มีเอกสาร (อื่น ๆ แล้วบางส่วนสะกดไม่ดีและส่วนใหญ่เป็นความคิดเห็นที่ไร้ประโยชน์ในไฟล์) ผังงานขนาดใหญ่ของไฟล์นั้นและเอกสารบางอย่างเกี่ยวกับวิธีการเชื่อมต่อมันจะดี แต่ดูเหมือนว่าจะขาดหายไปอย่างน่าเศร้า (หรืออย่างน้อยก็หาไม่เจอ)

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

อย่างไรก็ตามหลังจากขุดผ่านไฟล์ Microsoft.Web.Publishing.targets เป็นเวลาหลายชั่วโมงและกระแทกหัวของฉันกับกำแพงการทดลองและข้อผิดพลาดฉันได้จัดการเพื่อหาวิธีที่ Visual Studio ดูเหมือนจะทำงานได้อย่างวิเศษเพียงคลิกเดียว "เผยแพร่ไปยังระบบไฟล์" และคุณสมบัติ“ Build Deployment Package” ฉันจะเข้าสู่การเขียนสคริปต์ MSBuild เล็กน้อยดังนั้นหากคุณไม่คุ้นเคยกับ MSBuild ฉันขอแนะนำให้คุณดูหน้า MSDN ของหลักสูตรความผิดพลาดนี้

เผยแพร่ไปยังระบบไฟล์

กล่องโต้ตอบการเผยแพร่ไปยังระบบไฟล์ VS2010 การเผยแพร่ไปยังระบบไฟล์ใช้เวลาสักครู่ในการเลิกใช้เพราะฉันคาดว่าจะมีการใช้ MSBuild อย่างสมเหตุสมผล แต่ VS2010 กลับทำสิ่งที่ค่อนข้างแปลก: มันเรียก MSBuild เพื่อทำการปรับใช้แบบครึ่งหนึ่งซึ่งเตรียมไฟล์ของเว็บแอพในโฟลเดอร์ obj ของโปรเจ็กต์ของคุณจากนั้นดูเหมือนว่าจะทำสำเนาไฟล์เหล่านั้นด้วยตนเอง (เช่นภายนอก MSBuild) ลงในโฟลเดอร์เผยแพร่เป้าหมายของคุณ นี่เป็นพฤติกรรมการตีอย่างแท้จริงเนื่องจาก MSBuild ได้รับการออกแบบมาเพื่อคัดลอกไฟล์รอบ ๆ (และสิ่งอื่น ๆ ที่เกี่ยวข้องกับการสร้าง) ดังนั้นจึงสมเหตุสมผลถ้ากระบวนการทั้งหมดเป็นเพียงเป้าหมาย MSBuild เดียวที่ VS2010 เรียกร้องไม่ใช่เป้าหมายจากนั้นเป็นสำเนาคู่มือ

ซึ่งหมายความว่าการทำเช่นนี้ผ่าน MSBuild บนบรรทัดคำสั่งนั้นไม่ง่ายเหมือนกับการเรียกไฟล์โปรเจ็กต์ของคุณด้วยเป้าหมายเฉพาะและตั้งค่าคุณสมบัติบางอย่าง คุณจะต้องทำสิ่งที่ VS2010 ควรทำ: สร้างเป้าหมายด้วยตัวคุณเองที่ดำเนินการปรับใช้ครึ่งหนึ่งจากนั้นคัดลอกผลลัพธ์ไปยังโฟลเดอร์เป้าหมาย หากต้องการแก้ไขไฟล์โครงการของคุณให้คลิกขวาที่โครงการใน VS2010 แล้วคลิกยกเลิกการโหลดโครงการจากนั้นคลิกขวาอีกครั้งแล้วคลิกแก้ไข เลื่อนลงไปจนกว่าคุณจะพบอิลิเมนต์อิมพอร์ตที่อิมพอร์ตเป้าหมายเว็บแอ็พพลิเคชัน (Microsoft.WebApplication.targets ไฟล์นี้เองนำเข้าไฟล์ Microsoft.Web.Publishing.targets ที่กล่าวถึงก่อนหน้านี้) ภายใต้บรรทัดนี้เราจะเพิ่มเป้าหมายใหม่ของเราที่เรียกว่า PublishToFileSystem:

<Target Name="PublishToFileSystem"
        DependsOnTargets="PipelinePreDeployCopyAllFilesToOneFolder">
    <Error Condition="'$(PublishDestination)'==''"
           Text="The PublishDestination property must be set to the intended publishing destination." />
    <MakeDir Condition="!Exists($(PublishDestination))"
             Directories="$(PublishDestination)" />

    <ItemGroup>
        <PublishFiles Include="$(_PackageTempDir)\**\*.*" />
    </ItemGroup>

    <Copy SourceFiles="@(PublishFiles)"
          DestinationFiles="@(PublishFiles->'$(PublishDestination)\%(RecursiveDir)%(Filename)%(Extension)')"
          SkipUnchangedFiles="True" />
</Target>

เป้าหมายนี้ขึ้นอยู่กับเป้าหมาย PipelinePreDeployCopyAllFilesToOneFolder ซึ่งเป็นสิ่งที่ VS2010 เรียกก่อนที่จะทำสำเนาด้วยตนเอง การขุดรอบ ๆ ใน Microsoft.Web.Publishing.targets แสดงให้เห็นว่าการเรียกเป้าหมายนี้ทำให้ไฟล์โครงการถูกวางลงในไดเร็กทอรีที่ระบุโดยคุณสมบัติ _PackageTempDir

งานแรกที่เราเรียกในเป้าหมายของเราคืองาน Error ซึ่งเราได้วางเงื่อนไขที่ทำให้มั่นใจได้ว่างานจะเกิดขึ้นหากยังไม่ได้ตั้งค่าคุณสมบัติ PublishDestination สิ่งนี้จะจับคุณและสร้างข้อผิดพลาดในกรณีที่คุณลืมระบุคุณสมบัติ PublishDestination จากนั้นเราจะเรียกงาน MakeDir เพื่อสร้างไดเร็กทอรี PublishDestination หากยังไม่มีอยู่

จากนั้นเรากำหนดรายการที่เรียกว่า PublishFiles ซึ่งแสดงถึงไฟล์ทั้งหมดที่พบภายใต้โฟลเดอร์ _PackageTempDir จากนั้นงาน Copy จะถูกเรียกซึ่งคัดลอกไฟล์เหล่านั้นทั้งหมดไปยังโฟลเดอร์ Publish Destination แอตทริบิวต์ DestinationFiles ในองค์ประกอบ Copy ค่อนข้างซับซ้อน มันทำการแปลงไอเท็มและแปลงพา ธ ไปยังพา ธ ใหม่ที่รูทที่โฟลเดอร์ PublishDestination (ตรวจสอบข้อมูลเมตาของไอเท็มที่รู้จักกันดีเพื่อดูว่า% () หมายถึงอะไร)

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

msbuild Website.csproj "/p:Platform=AnyCPU;Configuration=Release;PublishDestination=F:\Temp\Publish" /t:PublishToFileSystem

3
ฉันไม่สามารถเข้าใจข้อมูลโค้ดสำหรับเป้าหมายใหม่ได้ (มันแสดง 01 02 03 ... ) คุณช่วยแก้ไขได้ไหม
fan711

2
ฉันเห็นด้วยกับ fan711 แม้ว่าวิธีการแก้ปัญหาจะอธิบายไว้ในลิงค์ - แล้วจะคัดลอกเพื่ออะไร?
АнтонКурьян

4
@ АнтонКурьян: ลิงก์มักจะหายไปหลังจากผ่านไประยะหนึ่งนั่นคือเหตุผลที่คำถามและคำตอบใน stackoverflow.com ควรอยู่ในตัวเองเสมอโดยไม่ต้องพึ่งพาทรัพยากรภายนอก
Oliver

ผลลัพธ์ดูเหมือนว่า MSBuild ไม่ได้ใช้โปรไฟล์การเผยแพร่เลยและเป็นการทำแพ็คเกจแทน (อาจเป็นค่าเริ่มต้น?) โซลูชันด้านล่างของคุณทำอะไรเพื่อจำลองสิ่งที่โปรไฟล์ถูกตั้งค่าให้ทำซึ่ง Microsoft.Web.Publishing.targets จัดการโดยการเลือกประเภทที่ถูกต้องจากโฟลเดอร์ปรับใช้ (สำหรับ FileSystem) ดูเหมือนว่าคุณกำลังสร้างวงล้อใหม่ที่นี่แทนที่จะแก้ปัญหานั้น แต่ไม่สามารถพูดได้อย่างแน่นอนหากไม่มีบันทึก MSBuild ของคุณ ฉันไปทำงานรายละเอียดในคำตอบของฉัน
GregS

1
วิธีแก้ปัญหาของ GregS ไม่ได้ผลสำหรับฉัน สร้างได้ดี แต่ไม่มีการคัดลอกไฟล์ไปยังไดเร็กทอรีการเผยแพร่
วิ่ง

19

ยังคงมีปัญหาหลังจากลองคำตอบทั้งหมดข้างต้น (ฉันใช้ Visual Studio 2013) ไม่มีการคัดลอกไปยังโฟลเดอร์เผยแพร่

สิ่งที่จับได้คือถ้าฉันเรียกใช้ MSBuild กับแต่ละโปรเจ็กต์แทนที่จะเป็นโซลูชันฉันต้องใส่พารามิเตอร์เพิ่มเติมที่ระบุเวอร์ชัน Visual Studio:

/p:VisualStudioVersion=12.0

12.0ใช้สำหรับ VS2013 แทนที่ด้วยเวอร์ชันที่คุณใช้ เมื่อฉันเพิ่มพารามิเตอร์นี้มันก็ใช้งานได้

บรรทัดคำสั่งที่สมบูรณ์มีลักษณะดังนี้:

MSBuild C:\PathToMyProject\MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=MyPublishProfile /p:VisualStudioVersion=12.0

ฉันพบที่นี่:

http://www.asp.net/mvc/overview/deployment/visual-studio-web-deployment/command-line-deployment

พวกเขาระบุ:

หากคุณระบุแต่ละโปรเจ็กต์แทนที่จะเป็นโซลูชันคุณต้องเพิ่มพารามิเตอร์ที่ระบุเวอร์ชัน Visual Studio


12

สำหรับฉันดูเหมือนว่าจะไม่มีการใช้โปรไฟล์การเผยแพร่ของคุณและกำลังทำบรรจุภัณฑ์เริ่มต้นบางอย่าง เป้าหมาย Microsoft Web Publish ทำทุกสิ่งที่คุณกำลังทำข้างต้นโดยจะเลือกเป้าหมายที่ถูกต้องตามการกำหนดค่า

ฉันทำให้ฉันทำงานได้โดยไม่มีปัญหาจากขั้นตอน TeamCity MSBuild แต่ฉันได้ระบุพา ธ ที่ชัดเจนไปยังโปรไฟล์คุณเพียงแค่เรียกมันด้วยชื่อโดยไม่มี. pdf (เช่น FileSystemDebug) จะพบได้นานพอ ๆ กับโฟลเดอร์มาตรฐานซึ่งเป็นของคุณ

ตัวอย่าง:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe ./ProjectRoot/MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=FileSystemDebug

โปรดทราบว่าสิ่งนี้ทำได้โดยใช้เป้าหมาย Microsoft Web Publish เวอร์ชัน Visual Studio 2012 โดยปกติจะอยู่ที่ "C: \ Program Files (x86) \ MSBuild \ Microsoft \ VisualStudio \ v11.0 \ Web" ตรวจสอบโฟลเดอร์ปรับใช้สำหรับเป้าหมายชนิดการปรับใช้เฉพาะที่ใช้


MS ได้ทำการปรับปรุงมากมายนับตั้งแต่มีการโพสต์เมื่อไม่กี่ปีที่ผ่านมาขอบคุณสำหรับการเขียนโปรแกรมที่อัปเดต?
พีรอ

3

FYI: ปัญหาเดียวกันกับการทำงานบนเซิร์ฟเวอร์ build (Jenkins ที่ติดตั้ง msbuild 15 ซึ่งขับเคลื่อนจาก VS 2017 บนเว็บโปรเจ็กต์. NET Core 2.1)

ในกรณีของฉันเป็นการใช้เป้าหมาย "เผยแพร่" กับ msbuild ที่ละเว้นโปรไฟล์

ดังนั้นคำสั่ง msbuild ของฉันจึงเริ่มต้นด้วย:

msbuild /t:restore;build;publish

สิ่งนี้ทริกเกอร์กระบวนการเผยแพร่อย่างถูกต้อง แต่ไม่มีการผสมหรือรูปแบบของ "/ p: PublishProfile = FolderProfile" เพื่อเลือกโปรไฟล์ที่ฉันต้องการใช้ ("FolderProfile")

เมื่อฉันหยุดใช้เป้าหมายการเผยแพร่:

msbuild /t:restore;build /p:DeployOnBuild=true /p:PublishProfile=FolderProfile

ฉัน (โง่เขลา) คิดว่ามันจะไม่สร้างความแตกต่าง แต่ทันทีที่ฉันใช้สวิตช์ DeployOnBuild มันก็หยิบโปรไฟล์ขึ้นมา


3

อันที่จริงฉันได้รวมคำตอบทั้งหมดของคุณเข้ากับวิธีแก้ปัญหาของฉันเองแล้ววิธีแก้ปัญหาข้างต้น:

  1. ฉันสร้างไฟล์ pubxml ตามความต้องการของฉัน
  2. จากนั้นฉันคัดลอกพารามิเตอร์ทั้งหมดจากไฟล์ pubxml ไปยังรายการพารามิเตอร์ของฉันเอง "/ p: foo = bar" สำหรับ msbuild.exe
  3. ฉันทิ้งไฟล์ pubxml

ผลลัพธ์เป็นเช่นนั้น:

msbuild /t:restore /t:build /p:WebPublishMethod=FileSystem /p:publishUrl=C:\builds\MyProject\ /p:DeleteExistingFiles=True /p:LastUsedPlatform="Any CPU" /p:Configuration=Release


1

ขั้นแรกให้ตรวจสอบเวอร์ชัน Visual studio ของพีซีสำหรับนักพัฒนาซึ่งสามารถเผยแพร่โซลูชัน (โครงการ) ได้ ตามที่แสดงสำหรับ VS 2013

 /p:VisualStudioVersion=12.0

เพิ่มบรรทัดคำสั่งด้านบนเพื่อระบุประเภทของ Visual Studio เวอร์ชันที่ควรสร้างโครงการ ตามคำตอบก่อนหน้านี้อาจเกิดขึ้นเมื่อเราพยายามเผยแพร่เพียงโครงการเดียวไม่ใช่วิธีแก้ปัญหาทั้งหมด

โค้ดที่สมบูรณ์จะเป็นแบบนี้

"C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ msbuild.exe" "C: \ Program Files (x86) \ Jenkins \ workspace \ Jenkinssecondsample \ MVCSampleJenkins \ MVCSampleJenkins.csproj" / T: Build; Package / p : Configuration = DEBUG / p: OutputPath = "obj \ DEBUG" / p: DeployIisAppPath = "เว็บไซต์เริ่มต้น / jenkinsdemoapp" /p:VisualStudioVersion=12.0


1
ขออภัยคุณ shammakalubo คุณตีความคำถามผิดไปมาก
P. Roe

1
@shammakalubo คำตอบถูก แต่ระบุไว้ไม่ครบถ้วน ต้องเพิ่มพารามิเตอร์นี้ในคำสั่งที่ OP กล่าวถึงซึ่งจะกลายเป็น: MSBuild C:\PathToMyProject\MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=MyPublishProfile /p:VisualStudioVersion=12.0พารามิเตอร์นี้คือสิ่งที่ฉันขาดหายไปและแก้ไขปัญหาของฉัน คุณต้องพูดถึงคำตอบให้ครบถ้วน!
Syed Waqas

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