คุณรวมไฟล์เพิ่มเติมโดยใช้แพ็คเกจการปรับใช้เว็บ VS2010 ได้อย่างไร


125

ฉันกำลังทดลองใช้ฟังก์ชันการทำงานของเว็บแพ็กเกจใหม่ใน Visual Studio 2010 และเจอสถานการณ์ที่ฉันใช้เหตุการณ์ที่สร้างไว้ล่วงหน้าเพื่อคัดลอก. dll ที่จำเป็นไปยังโฟลเดอร์ bin ของฉันที่แอปของฉันใช้สำหรับการเรียก API ไม่สามารถรวมเป็นข้อมูลอ้างอิงเนื่องจากไม่ใช่ COM dll ที่สามารถใช้กับ interop ได้

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

คำตอบ:


176

คำถามที่ดี ฉันเพียงแค่โพสต์รายการบล็อกรายละเอียดมากเกี่ยวกับเรื่องนี้ในเว็บเครื่องมือการจัดวาง (MSDeploy): สร้างแพคเกจรวมถึงไฟล์พิเศษหรือไม่รวมไฟล์ที่เฉพาะเจาะจง

นี่คือเรื่องย่อ หลังจากรวมไฟล์แล้วฉันจะแสดงวิธีการยกเว้นไฟล์ด้วย

รวมถึงไฟล์พิเศษ

การรวมไฟล์พิเศษลงในแพ็คเกจนั้นยากกว่าเล็กน้อย แต่ก็ยังไม่มีปัญหาหากคุณพอใจกับ MSBuild และถ้าคุณไม่ได้อ่านสิ่งนี้ ในการดำเนินการนี้เราจำเป็นต้องเชื่อมโยงเข้าไปในส่วนของกระบวนการที่รวบรวมไฟล์สำหรับบรรจุภัณฑ์ เป้าหมายที่เราต้องการขยายเรียกว่า CopyAllFilesToSingleFolder เป้าหมายนี้มีคุณสมบัติการพึ่งพา PipelinePreDeployCopyAllFilesToOneFolderDependsOn ที่เราสามารถแตะและฉีดเป้าหมายของเราเองได้ ดังนั้นเราจะสร้างเป้าหมายชื่อ CustomCollectFiles และฉีดเข้าไปในกระบวนการ เราบรรลุสิ่งนี้ด้วยสิ่งต่อไปนี้ (จำไว้หลังคำสั่งนำเข้า)

<PropertyGroup>
  <CopyAllFilesToSingleFolderForPackageDependsOn>
    CustomCollectFiles;
    $(CopyAllFilesToSingleFolderForPackageDependsOn);
  </CopyAllFilesToSingleFolderForPackageDependsOn>

  <CopyAllFilesToSingleFolderForMsdeployDependsOn>
    CustomCollectFiles;
    $(CopyAllFilesToSingleFolderForMsdeployDependsOn);
  </CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>

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

<Target Name="CustomCollectFiles">
  <ItemGroup>
    <_CustomFiles Include="..\Extra Files\**\*" />

    <FilesForPackagingFromProject  Include="%(_CustomFiles.Identity)">
      <DestinationRelativePath>Extra Files\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
    </FilesForPackagingFromProject>
  </ItemGroup>
</Target>

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

จากนั้นฉันใช้รายการนี้เพื่อเติมข้อมูลรายการ FilesForPackagingFromProject นี่คือรายการที่ MSDeploy ใช้เพื่อเพิ่มไฟล์พิเศษ โปรดสังเกตด้วยว่าฉันประกาศค่า DestinationRelativePath ของข้อมูลเมตา สิ่งนี้จะกำหนดเส้นทางสัมพัทธ์ที่จะวางไว้ในแพ็คเกจ ฉันใช้คำสั่ง Extra Files% (RecursiveDir)% (Filename)% (Extension) ที่นี่ สิ่งที่พูดคือการวางไว้ในตำแหน่งสัมพัทธ์เดียวกันในแพ็คเกจเนื่องจากอยู่ในโฟลเดอร์ Extra Files

การยกเว้นไฟล์

หากคุณเปิดไฟล์โครงการของเว็บแอปพลิเคชันที่สร้างด้วย VS 2010 ที่ด้านล่างคุณจะพบบรรทัดที่มี

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

BTW คุณสามารถเปิดไฟล์โครงการภายใน VS. คลิกขวาที่โครงการเลือก Unload Project จากนั้นคลิกขวาที่โครงการที่ไม่ได้โหลดแล้วเลือกแก้ไขโครงการ

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

<ItemGroup>
  <ExcludeFromPackageFiles Include="Sample.Debug.xml">
    <FromTarget>Project</FromTarget>
  </ExcludeFromPackageFiles>
</ItemGroup>

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


3
คุณสามารถขยายตัวอย่างของคุณเพื่อรวมเอาท์พุทโครงการเพิ่มเติมในการเผยแพร่ได้หรือไม่?
Anthony Serdyukov

7
ฉันติดตั้ง VS2012 (RC) แล้วและสำหรับฉันมี DependencyProperty ที่แตกต่างกัน เพื่อสนับสนุนทีมผสม (และบิลด์เซิร์ฟเวอร์ของเรา) ฉันมีการกำหนดค่า CopyAllFilesToSingleFolderForPackageDependsOn ดั้งเดิมและการทำซ้ำโดยใช้ DependencyProperty CopyAllFilesToSingleFolderForMsdeployDependsOn
Emil Lerch

2
นี่มันวิเศษมาก ใช้สิ่งนี้เพื่อปรับใช้ข้อมูลเวอร์ชันบางส่วนที่เก็บไว้ในไฟล์ txt
lamarant

5
ดูเหมือนจะไม่ได้ผลสำหรับฉัน ฉันใช้ VStudio 2013 :( การตั้งค่า msbuild ข้างต้นใช้งานได้ในปี 2013 หรือไม่
irperez

8
@SayedIbrahimHashimi และ co. ได้สร้างรุ่นอื่น ๆ อีกมากมายขึ้นไปวันที่ของคู่มือนี้บนเว็บไซต์ asp.net ฉันขอแนะนำให้ลิงก์นั้นเนื่องจากนั่นเป็นความแตกต่างระหว่างฉันที่ติดขัดในการแก้ไขไฟล์ csproj แทนที่จะเป็นไฟล์ pubxml
Adam Venezia

21

วิธีแก้ไขที่ง่ายกว่าคือแก้ไขไฟล์ csproj เพื่อรวม dll ที่ต้องการไว้ในโฟลเดอร์ bin จากนั้นสร้างเป้าหมายก่อนสร้างเพื่อคัดลอกรายการไปยังโฟลเดอร์ bin จากโฟลเดอร์ไลบรารีทั่วไปที่เราเก็บ dll ของบุคคลที่สามของเรา เนื่องจากไอเท็มมีอยู่ในไฟล์โซลูชันจึงถูกปรับใช้โดย msbuild / msdeploy และไม่จำเป็นต้องมีอะไรซับซ้อน

แท็กที่ใช้เพื่อรวมไฟล์โดยไม่ต้องเพิ่มผ่าน VS (ซึ่งมักจะต้องการเพิ่มลงใน VCS ของคุณ)

<Content Include="Bin\3rdPartyNative.dll" ><Visible>false</Visible></Content>

นี่คือเป้าหมาย BeforeBuild ที่เหมาะกับฉัน:

<Target Name="BeforeBuild">
    <Message Text="Copy $(SolutionDir)Library\3rdPartyNative.dll to '$(TargetDir)'3rdPartyNative.dll" Importance="high" />
    <Copy SourceFiles="$(SolutionDir)Library\3rdPartyNative.dll" DestinationFiles="$(TargetDir)3rdPartyNative.dll" />
</Target>

แก้ไขเพื่อรวมคำแนะนำของ @ tuespetre เพื่อซ่อนรายการดังนั้นจึงลบข้อเสียก่อนหน้าของโฟลเดอร์ bin ที่มองเห็นได้ ฉันไม่ได้รับการยืนยัน


3
"ความเรียบง่ายคือความซับซ้อนขั้นสูงสุด"
BornToCode

1
วิธีนี้ใช้ได้ผลในหลาย ๆ กรณี แต่จะไม่ได้ผลหากคุณมีไฟล์ที่ต้องรวมไว้นอกโฟลเดอร์ bin
นาธาน

5
@toxaq ฉันอาจจะขาดอะไรไป แต่ปัญหาที่ฉันพบคือฉันต้องการไฟล์ในตำแหน่งที่ตั้งในแพ็คเกจการปรับใช้ที่ไม่ได้อยู่ในโฟลเดอร์ bin ใช่คุณสามารถคัดลอกไฟล์จากที่ใดก็ได้ไปยังโฟลเดอร์ bin แต่จะไม่รวมอยู่ในตำแหน่งที่ถูกต้องในแพ็คเกจการปรับใช้ในสถานการณ์นั้น สำหรับสิ่งที่คุ้มค่าสถานการณ์ที่ฉันพบคือกับโปรเจ็กต์ ClearScript.V8 - .dlls ดั้งเดิมต้องไม่ปรากฏในไดเร็กทอรี bin แต่ต้องปรากฏในพาเรนต์ - ดูที่clearscript.codeplex.com/discussions/438696สำหรับการสนทนา .
นาธาน

3
ฉันจะโหวตเพิ่มอีกสิบครั้งถ้าทำได้ นี่ควรเป็นคำตอบที่ได้รับการยอมรับ ฉันต้องการเพิ่มว่าคุณสามารถตั้งค่า<Visible>false</Visible>ให้ซ่อนจาก Solution Explorer ได้
อังคาร

1
@Tohid ขอบคุณได้ทำการแก้ไขนั้น ไม่มี MS ให้ทดสอบดังนั้นฉันจึงไม่ได้ตรวจสอบ
toxaq

7

เช่นเดียวกับ @toxaq แต่วิธีที่ง่ายกว่านั้นคือ:

ในโซลูชัน explorer ให้เพิ่มไฟล์เป็นลิงก์ไปยังโฟลเดอร์ไลบรารี / การอ้างอิงจากนั้นในคุณสมบัติตั้งค่าให้คัดลอกไปยังเอาต์พุตของบิลด์


3
-1 สิ่งนี้ถือว่าโครงการต้องการมีความสัมพันธ์เวลาเชื่อมโยงอย่างชัดเจน ไม่เหมาะสำหรับระบบประเภทปลั๊กอิน
MickyD

6

ดังนั้นการใช้งานของ Sayed จึงไม่ได้ผลสำหรับฉัน ฉันใช้ VS2013 และใช้แพ็คเกจ Web Deploy และจำเป็นต้องเพิ่มปลั๊กอิน DLL จากโฟลเดอร์อื่นลงในถังของแพ็คเกจปรับใช้ นี่คือวิธีที่ฉันจัดการเพื่อให้ใช้งานได้ (ง่ายขึ้นมาก):

ที่ด้านล่างของไฟล์ csproj ของคุณเพิ่ม:

<Target Name="AdditionalFilesForPackage" AfterTargets="CopyAllFilesToSingleFolderForMsdeploy">
    <ItemGroup> 
        <Files Include="..\SomeOtherProject\bin\$(Configuration)\*.*"/>
    </ItemGroup>
    <Copy SourceFiles="@(Files)" DestinationFolder="$(_PackageTempDir)\bin\" />  
</Target>

สิ่งที่กล่าวถึงอื่น ๆ ในไฟล์ csproj:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <DeployOnBuild>true</DeployOnBuild>
    <DeployTarget>Package</DeployTarget>
    <DeployIisAppPath>Default Web Site/MyWebsite</DeployIisAppPath>
    <DesktopBuildPackageLocation>..\output\Service\Service\Service.Release.zip</DesktopBuildPackageLocation>
    <FilesToIncludeForPublish>OnlyFilesToRunTheApp</FilesToIncludeForPublish>
    <ExcludeGeneratedDebugSymbol>true</ExcludeGeneratedDebugSymbol>
    <PublishDatabases>false</PublishDatabases>
</PropertyGroup>

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

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

5

ต้องการแสดงความคิดเห็นเพื่อเน้นย้ำความคิดเห็นของ Emil Lerch ด้านบน หากคุณติดตั้ง Azure SDK แล้วให้มองหา DependencyProperty อื่น

โดยทั่วไปคุณอาจต้องใช้ "CopyAllFilesToSingleFolderForMsdeployDependsOn แทน" CopyAllFilesToSingleFolderForPackageDependsOn "ฉันไม่ใช่ MsBuild ขั้นสูงจริงๆและฉันเสียเวลาหลายชั่วโมงในการดึงผมออกเพื่อพยายามหาสาเหตุว่าทำไมเป้าหมายของฉันจึงไม่ถูกเรียก

นี่คือลิงค์อื่นหากไม่ได้ผลสำหรับคุณและคุณได้ติดตั้ง Azure SDK: http://forums.iis.net/t/1190714.aspx


3

ในฐานะที่เป็นภาคผนวกสำหรับคำตอบของ Sayed ฉันพบว่าการประกาศแบบคงที่ของรายการ ExcludeFromPackageFiles ภายในโครงการของฉันไม่เพียงพอ ฉันต้องการแยก DLL บางตัวที่พร้อมใช้งานหลังจากคอมไพล์แล้วเท่านั้น(โมดูล Ninject เฉพาะของ Azure ที่ไม่จำเป็นเมื่อฉันปรับใช้กับ IIS)

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

<PropertyGroup>
    <ExcludeFilesFromPackageDependsOn>
        $(ExcludeFilesFromPackageDependsOn);
        _ExcludeAzureDlls
    </ExcludeFilesFromPackageDependsOn>
</PropertyGroup>

<Target Name="_ExcludeAzureDlls">
    <ItemGroup>
        <FilesForPackagingFromProjectWithNoAzure Include="@(FilesForPackagingFromProject)"
                               Exclude="%(RootDir)%(Directory)*Azure*.dll" />
        <AzureFiles Include="@(FilesForPackagingFromProject)"
                    Exclude="@(FilesForPackagingFromProjectWithNoAzure)" />
        <ExcludeFromPackageFiles Include="@(AzureFiles)">
            <FromTarget>_ExcludeAzureEnvironmentDlls</FromTarget>
        </ExcludeFromPackageFiles>
    </ItemGroup>
</Target>

หวังว่าจะช่วยใครสักคน ...


1

นอกจากนี้ยังสามารถตั้งค่าไฟล์เป็นเนื้อหา | คัดลอกเสมอ

นอกจากนี้ยังสามารถตั้งค่าไฟล์เป็นเนื้อหา |  คัดลอกเสมอ


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